1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-27 23:36:35 +00:00

version 1.2018.9

This commit is contained in:
Arnaud Roques 2018-07-27 23:56:46 +02:00
parent a363246176
commit 87ee4898b1
108 changed files with 2665 additions and 1006 deletions

View File

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

View File

@ -38,17 +38,18 @@ package net.sourceforge.plantuml;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
public enum AlignParam {
public enum AlignmentParam {
ARROW_MESSAGE_ALIGN(HorizontalAlignment.LEFT),
SEQUENCE_MESSAGE_ALIGN(HorizontalAlignment.LEFT),
SEQUENCE_MESSAGETEXT_ALIGN(HorizontalAlignment.LEFT),
SEQUENCE_REFERENCE_ALIGN(HorizontalAlignment.CENTER),
PACKAGE_TITLE_ALIGNMENT(HorizontalAlignment.CENTER);
arrowMessageAlignment(HorizontalAlignment.LEFT),
sequenceMessageAlignment(HorizontalAlignment.LEFT),
sequenceMessageTextAlignment(HorizontalAlignment.LEFT),
sequenceReferenceAlignment(HorizontalAlignment.CENTER),
packageTitleAlignment(HorizontalAlignment.CENTER),
noteTextAlignment(HorizontalAlignment.LEFT);
private final HorizontalAlignment defaultValue;
private AlignParam(HorizontalAlignment defaultValue) {
private AlignmentParam(HorizontalAlignment defaultValue) {
this.defaultValue = defaultValue;
}

View File

@ -173,9 +173,9 @@ public class BlockUml {
return data.get(0).toString().equalsIgnoreCase(signature);
}
public List<? extends CharSequence> getDefinition() {
if (data.get(0).toString().startsWith("@startdef") == false) {
throw new IllegalStateException();
public List<? extends CharSequence> getDefinition(boolean withHeader) {
if (withHeader) {
return Collections.unmodifiableList(data);
}
return Collections.unmodifiableList(data.subList(1, data.size() - 1));
}

View File

@ -141,7 +141,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
for (BlockUml block : blocks) {
if (block.isStartDef(name)) {
this.defines.importFrom(block.getLocalDefines());
return block.getDefinition();
return block.getDefinition(false);
}
}
return Collections.emptyList();

View File

@ -56,11 +56,11 @@ public class EmptyImageBuilder {
public EmptyImageBuilder(int width, int height, Color background) {
if (width > GraphvizUtils.getenvImageLimit()) {
Log.info("Width too large " + width);
Log.info("Width too large " + width + ". You should set PLANTUML_LIMIT_SIZE");
width = GraphvizUtils.getenvImageLimit();
}
if (height > GraphvizUtils.getenvImageLimit()) {
Log.info("Height too large " + height);
Log.info("Height too large " + height + ". You should set PLANTUML_LIMIT_SIZE");
height = GraphvizUtils.getenvImageLimit();
}
Log.info("Creating image " + width + "x" + height);

View File

@ -55,7 +55,7 @@ import net.sourceforge.plantuml.ugraphic.UFont;
*
*/
public enum FileFormat {
PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, SCXML, PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, LATEX_NO_PREAMBLE, BASE64, BRAILLE_PNG;
PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, SCXML, PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, LATEX_NO_PREAMBLE, BASE64, BRAILLE_PNG, PREPROC;
/**
* Returns the file format to be used for that format.

View File

@ -51,6 +51,8 @@ import net.sourceforge.plantuml.ugraphic.UStroke;
public interface ISkinParam extends ISkinSimple {
public static final int SWIMLANE_WIDTH_SAME = -1;
public HtmlColor getHyperlinkColor();
public boolean useUnderlineForHyperlink();
@ -67,7 +69,7 @@ public interface ISkinParam extends ISkinSimple {
public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam);
public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection);
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection);
public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue);
@ -109,6 +111,8 @@ public interface ISkinParam extends ISkinSimple {
public LineBreakStrategy wrapWidth();
public LineBreakStrategy swimlaneWrapTitleWidth();
public boolean strictUmlStyle();
public boolean forceSequenceParticipantUnderlined();

View File

@ -45,7 +45,11 @@ public class LineBreakStrategy {
this.value = value;
}
public double getMathWidth() {
public boolean isAuto() {
return "auto".equalsIgnoreCase(value);
}
public double getMaxWidth() {
if (value != null && value.matches("-?\\d+")) {
return Double.parseDouble(value);
}

View File

@ -68,6 +68,7 @@ public class Option {
private boolean pipeNoStdErr = false;
private boolean syntax = false;
private boolean checkOnly = false;
private OptionPreprocOutputMode preprocessorOutput = null;
private boolean failfast = false;
private boolean failfast2 = false;
private boolean pattern = false;
@ -332,6 +333,10 @@ public class Option {
textProgressBar = true;
} else if (s.equalsIgnoreCase("-nometadata")) {
hideMetadata = true;
} else if (s.equalsIgnoreCase("-preproc")) {
preprocessorOutput = OptionPreprocOutputMode.NORMAL;
} else if (s.equalsIgnoreCase("-cypher")) {
preprocessorOutput = OptionPreprocOutputMode.CYPHER;
} else if (s.equalsIgnoreCase("-checkmetadata")) {
checkMetadata = true;
} else if (s.equalsIgnoreCase("-pipeimageindex")) {
@ -588,4 +593,12 @@ public class Option {
return checkMetadata;
}
public final OptionPreprocOutputMode getPreprocessorOutputMode() {
return preprocessorOutput;
}
// public final void setPreprocessorOutput(boolean preprocessorOutput) {
// this.preprocessorOutput = preprocessorOutput;
// }
}

View File

@ -0,0 +1,41 @@
/* ========================================================================
* 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;
public enum OptionPreprocOutputMode {
NORMAL, CYPHER
}

View File

@ -142,9 +142,10 @@ public class OptionPrint {
System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
System.out.println(" -progress\t\tTo display a textual progress bar in console");
System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
System.out.println(" -stdlib\tTo print standart library info");
System.out.println(" -stdlib\t\tTo print standart library info");
System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
System.out.println();
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
exit();

View File

@ -71,6 +71,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt;
import net.sourceforge.plantuml.version.LicenseInfo;
import net.sourceforge.plantuml.version.PSystemVersion;
public class PSystemError extends AbstractPSystem {
@ -144,9 +145,11 @@ public class PSystemError extends AbstractPSystem {
} else {
udrawable = result;
}
final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
if (min == 0) {
udrawable = addMessage(udrawable);
if (LicenseInfo.retrieveQuick().isValid() == false) {
final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
if (min == 0) {
udrawable = addMessage(udrawable);
}
}
imageBuilder.setUDrawable(udrawable);
final ImageData imageData = imageBuilder.writeImageTOBEMOVED(fileFormat, seed(), os);

View File

@ -43,6 +43,9 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
@ -67,12 +70,16 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.StatsUtils;
import net.sourceforge.plantuml.swing.MainWindow2;
import net.sourceforge.plantuml.syntax.LanguageDescriptor;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteGrayLevel;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteUtils;
import net.sourceforge.plantuml.utils.Cypher;
import net.sourceforge.plantuml.version.Version;
public class Run {
private static Cypher cypher;
public static void main(String[] argsArray) throws IOException, InterruptedException {
System.setProperty("log4j.debug", "false");
final long start = System.currentTimeMillis();
@ -135,6 +142,9 @@ public class Run {
}
forceOpenJdkResourceLoad();
if (option.getPreprocessorOutputMode() == OptionPreprocOutputMode.CYPHER) {
cypher = new LanguageDescriptor().getCypher();
}
boolean error = false;
boolean forceQuit = false;
if (option.isPattern()) {
@ -231,10 +241,13 @@ public class Run {
return false;
}
static private final String httpProtocol = "http://";
static private final String httpsProtocol = "https://";
private static void encodeSprite(List<String> result) throws IOException {
SpriteGrayLevel level = SpriteGrayLevel.GRAY_16;
boolean compressed = false;
final File f;
final String path;
if (result.size() > 1 && result.get(0).matches("(4|8|16)z?")) {
if (result.get(0).startsWith("8")) {
level = SpriteGrayLevel.GRAY_8;
@ -243,28 +256,52 @@ public class Run {
level = SpriteGrayLevel.GRAY_4;
}
compressed = StringUtils.goLowerCase(result.get(0)).endsWith("z");
f = new File(result.get(1));
path = result.get(1);
} else {
f = new File(result.get(0));
path = result.get(0);
}
final BufferedImage im = ImageIO.read(f);
final String name = getSpriteName(f);
final String fileName;
final URL source;
final String lowerPath = StringUtils.goLowerCase(path);
if (lowerPath.startsWith(httpProtocol) || lowerPath.startsWith(httpsProtocol)) {
source = new URL(path);
final String p = source.getPath();
fileName = p.substring(p.lastIndexOf('/') + 1, p.length());
} else {
final File f = new File(path);
source = f.toURI().toURL();
fileName = f.getName();
}
InputStream stream = null;
final BufferedImage im;
try {
stream = source.openStream();
im = ImageIO.read(stream);
} finally {
if (stream != null) {
stream.close();
}
}
final String name = getSpriteName(fileName);
final String s = compressed ? SpriteUtils.encodeCompressed(im, name, level) : SpriteUtils.encode(im, name,
level);
System.out.println(s);
}
private static String getSpriteName(File f) {
final String s = getSpriteNameInternal(f);
private static String getSpriteName(String fileName) {
final String s = getSpriteNameInternal(fileName);
if (s.length() == 0) {
return "test";
}
return s;
}
private static String getSpriteNameInternal(File f) {
private static String getSpriteNameInternal(String fileName) {
final StringBuilder sb = new StringBuilder();
for (char c : f.getName().toCharArray()) {
for (char c : fileName.toCharArray()) {
if (("" + c).matches("[\\p{L}0-9_]")) {
sb.append(c);
} else {
@ -291,7 +328,6 @@ public class Run {
for (String n : name) {
System.out.println("n=" + n);
}
}
private static void managePattern() {
@ -356,6 +392,7 @@ public class Run {
files.addAll(group.getFiles());
}
}
Log.info("Found " + files.size() + " files");
for (File f : files) {
try {
final boolean error = manageFileInternal(f, option);
@ -417,6 +454,7 @@ public class Run {
}
private static boolean manageFileInternal(File f, Option option) throws IOException, InterruptedException {
Log.info("Working on " + f.getAbsolutePath());
if (OptionFlags.getInstance().isExtractFromMetadata()) {
System.out.println("------------------------");
System.out.println(f);
@ -435,6 +473,7 @@ public class Run {
option.getConfig(), option.getCharset(), option.getFileFormatOption());
}
sourceFileReader.setCheckMetadata(option.isCheckMetadata());
if (option.isComputeurl()) {
for (BlockUml s : sourceFileReader.getBlocks()) {
System.out.println(s.getEncodedUrl());
@ -447,10 +486,33 @@ public class Run {
hasErrors(f, result);
return hasError;
}
if (option.getPreprocessorOutputMode() != null) {
extractPreproc(option, sourceFileReader);
return false;
}
final List<GeneratedImage> result = sourceFileReader.getGeneratedImages();
return hasErrors(f, result);
}
private static void extractPreproc(Option option, final ISourceFileReader sourceFileReader) throws IOException {
final String charset = option.getCharset();
for (BlockUml blockUml : sourceFileReader.getBlocks()) {
final SuggestedFile suggested = ((SourceFileReaderAbstract) sourceFileReader).getSuggestedFile(blockUml)
.withPreprocFormat();
final File file = suggested.getFile(0);
Log.info("Export preprocessing source to " + file.getAbsolutePath());
final PrintWriter pw = charset == null ? new PrintWriter(file) : new PrintWriter(file, charset);
for (CharSequence s : blockUml.getDefinition(true)) {
if (cypher != null) {
s = cypher.cypher(s.toString());
}
pw.println(s);
}
pw.close();
}
}
private static boolean hasErrors(File f, final List<GeneratedImage> list) throws IOException {
boolean result = false;
for (GeneratedImage i : list) {

View File

@ -42,18 +42,30 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import net.sourceforge.plantuml.code.AsciiEncoder;
public class SignatureUtils {
public static byte[] salting(String pass, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException,
UnsupportedEncodingException {
final int iterations = 10000;
final int keyLength = 512;
final SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
final PBEKeySpec spec = new PBEKeySpec(pass.toCharArray(), salt, iterations, keyLength);
final SecretKey key = skf.generateSecret(spec);
return SignatureUtils.getSHA512raw(key.getEncoded());
}
public static String getSignature(String s) {
try {
final AsciiEncoder coder = new AsciiEncoder();
final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
msgDigest.update(s.getBytes("UTF-8"));
final byte[] digest = msgDigest.digest();
return coder.encode(digest);
final byte[] digest = getMD5raw(s);
return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@ -63,21 +75,24 @@ public class SignatureUtils {
}
}
public static String getMD5(String s) {
public static String toString(byte data[]) {
final AsciiEncoder coder = new AsciiEncoder();
return coder.encode(data);
}
public static String toHexString(byte data[]) {
final StringBuilder sb = new StringBuilder(data.length * 2);
for (byte b : data) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static String getMD5Hex(String s) {
try {
final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
msgDigest.update(s.getBytes("UTF-8"));
final byte[] digest = msgDigest.digest();
final StringBuilder result = new StringBuilder(32);
for (byte b : digest) {
final String tmp = Integer.toHexString(b & 0xFF);
if (tmp.length() == 1) {
result.append("0");
}
result.append(tmp);
}
assert result.length() == 32;
return result.toString();
final byte[] digest = getMD5raw(s);
assert digest.length == 16;
return toHexString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@ -87,6 +102,36 @@ public class SignatureUtils {
}
}
public static String getSHA512Hex(String s) {
try {
final byte[] digest = getSHA512raw(s);
assert digest.length == 64;
return toHexString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
}
}
public static byte[] getMD5raw(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
msgDigest.update(s.getBytes("UTF-8"));
return msgDigest.digest();
}
public static byte[] getSHA512raw(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
return getSHA512raw(s.getBytes("UTF-8"));
}
public static byte[] getSHA512raw(byte data[]) throws NoSuchAlgorithmException, UnsupportedEncodingException {
final MessageDigest msgDigest = MessageDigest.getInstance("SHA-512");
msgDigest.update(data);
return msgDigest.digest();
}
public static String getSignatureSha512(File f) throws IOException {
final InputStream is = new FileInputStream(f);
try {
@ -98,14 +143,13 @@ public class SignatureUtils {
public static String getSignatureSha512(InputStream is) throws IOException {
try {
final AsciiEncoder coder = new AsciiEncoder();
final MessageDigest msgDigest = MessageDigest.getInstance("SHA-512");
int read = 0;
while ((read = is.read()) != -1) {
msgDigest.update((byte) read);
}
final byte[] digest = msgDigest.digest();
return coder.encode(digest);
return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@ -130,7 +174,6 @@ public class SignatureUtils {
public static String getSignature(File f) throws IOException {
try {
final AsciiEncoder coder = new AsciiEncoder();
final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
final FileInputStream is = new FileInputStream(f);
int read = -1;
@ -139,7 +182,7 @@ public class SignatureUtils {
}
is.close();
final byte[] digest = msgDigest.digest();
return coder.encode(digest);
return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);

View File

@ -137,6 +137,7 @@ public class SkinParam implements ISkinParam {
key = key.replaceAll("statearrow", "arrow");
key = key.replaceAll("usecasearrow", "arrow");
key = key.replaceAll("sequencearrow", "arrow");
key = key.replaceAll("align$", "alignment");
final Matcher2 mm = stereoPattern.matcher(key);
final List<String> result = new ArrayList<String>();
while (mm.find()) {
@ -427,7 +428,9 @@ public class SkinParam implements ISkinParam {
result.add("PageBorderColor");
result.add("PageExternalColor");
result.add("PageMargin");
result.add("WrapWidth");
result.add("SwimlaneWidth");
result.add("SwimlaneWrapTitleWidth");
for (FontParam p : EnumSet.allOf(FontParam.class)) {
final String h = humanName(p.name());
@ -444,6 +447,10 @@ public class SkinParam implements ISkinParam {
final String h = capitalize(p.name());
result.add(h + "Thickness");
}
for (AlignmentParam p : EnumSet.allOf(AlignmentParam.class)) {
final String h = capitalize(p.name());
result.add(h);
}
return Collections.unmodifiableSet(result);
}
@ -470,14 +477,14 @@ public class SkinParam implements ISkinParam {
return DotSplines.SPLINES;
}
public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection) {
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection) {
final String value;
switch (param) {
case SEQUENCE_MESSAGE_ALIGN:
value = getArg(getValue(AlignParam.SEQUENCE_MESSAGE_ALIGN.name()), 0);
case sequenceMessageAlignment:
value = getArg(getValue(AlignmentParam.sequenceMessageAlignment.name()), 0);
break;
case SEQUENCE_MESSAGETEXT_ALIGN:
value = getArg(getValue(AlignParam.SEQUENCE_MESSAGE_ALIGN.name()), 1);
case sequenceMessageTextAlignment:
value = getArg(getValue(AlignmentParam.sequenceMessageAlignment.name()), 1);
break;
default:
value = getValue(param.name());
@ -489,6 +496,9 @@ public class SkinParam implements ISkinParam {
if (arrowDirection == ArrowDirection.RIGHT_TO_LEFT_REVERSE) {
return HorizontalAlignment.RIGHT;
}
if (arrowDirection == ArrowDirection.BOTH_DIRECTION) {
return HorizontalAlignment.CENTER;
}
}
if ("reversedirection".equalsIgnoreCase(value)) {
if (arrowDirection == ArrowDirection.LEFT_TO_RIGHT_NORMAL) {
@ -497,9 +507,14 @@ public class SkinParam implements ISkinParam {
if (arrowDirection == ArrowDirection.RIGHT_TO_LEFT_REVERSE) {
return HorizontalAlignment.LEFT;
}
if (arrowDirection == ArrowDirection.BOTH_DIRECTION) {
return HorizontalAlignment.CENTER;
}
}
final HorizontalAlignment result = HorizontalAlignment.fromString(value);
if (result == null) {
if (result == null && param == AlignmentParam.noteTextAlignment) {
return getDefaultTextAlignment(HorizontalAlignment.LEFT);
} else if (result == null) {
return param.getDefaultValue();
}
return result;
@ -755,6 +770,11 @@ public class SkinParam implements ISkinParam {
return new LineBreakStrategy(value);
}
public LineBreakStrategy swimlaneWrapTitleWidth() {
final String value = getValue("swimlanewraptitlewidth");
return new LineBreakStrategy(value);
}
public boolean strictUmlStyle() {
final String value = getValue("style");
if ("strictuml".equalsIgnoreCase(value)) {
@ -917,7 +937,7 @@ public class SkinParam implements ISkinParam {
public int swimlaneWidth() {
final String value = getValue("swimlanewidth");
if ("same".equalsIgnoreCase(value)) {
return -1;
return SWIMLANE_WIDTH_SAME;
}
if (value != null && value.matches("\\d+")) {
return Integer.parseInt(value);

View File

@ -103,7 +103,7 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getDotExecutable();
}
public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection) {
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection) {
return skinParam.getHorizontalAlignment(param, arrowDirection);
}
@ -295,4 +295,8 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getCircledCharacter(stereotype);
}
public LineBreakStrategy swimlaneWrapTitleWidth() {
return skinParam.swimlaneWrapTitleWidth();
}
}

View File

@ -140,7 +140,7 @@ public abstract class SourceFileReaderAbstract {
final List<GeneratedImage> result = new ArrayList<GeneratedImage>();
for (BlockUml blockUml : builder.getBlockUmls()) {
SuggestedFile suggested = getSuggestedFile(blockUml);
final SuggestedFile suggested = getSuggestedFile(blockUml);
final Diagram system;
try {

View File

@ -52,6 +52,10 @@ public class SuggestedFile {
this.initialCpt = initialCpt;
}
public SuggestedFile withPreprocFormat() {
return new SuggestedFile(outputFile, FileFormat.PREPROC, initialCpt);
}
@Override
public String toString() {
return outputFile.getAbsolutePath() + "[" + initialCpt + "]";

View File

@ -48,8 +48,11 @@ public class SvgString {
this.scale = scale;
}
public String getSvg() {
public String getSvg(boolean raw) {
String result = svg;
if (raw) {
return result;
}
if (result.startsWith("<?xml")) {
final int idx = result.indexOf("<svg");
result = result.substring(idx);

View File

@ -270,7 +270,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann
graphicStrings.drawU(ug);
final double height = graphicStrings.calculateDimension(ug.getStringBounder()).getHeight();
ug = ug.apply(new UTranslate(0, height));
ug.draw(new UImage(im));
ug.draw(new UImage(im).scaleNearestNeighbor(3));
}
});
}

View File

@ -48,7 +48,7 @@ import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlanes;
import net.sourceforge.plantuml.activitydiagram3.ftile.SwimlanesC;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
@ -56,12 +56,13 @@ import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockCompressed;
import net.sourceforge.plantuml.graphic.TextBlockRecentred;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import net.sourceforge.plantuml.ugraphic.comp.CompressionMode;
import net.sourceforge.plantuml.ugraphic.comp.TextBlockCompressedOnXorY;
public class ActivityDiagram3 extends UmlDiagram {
@ -71,7 +72,7 @@ public class ActivityDiagram3 extends UmlDiagram {
private SwimlaneStrategy swimlaneStrategy;
private final Swimlanes swinlanes = new Swimlanes(getSkinParam(), getPragma());
private final SwimlanesC swinlanes = new SwimlanesC(getSkinParam(), getPragma());
private void manageSwimlaneStrategy() {
if (swimlaneStrategy == null) {
@ -191,8 +192,10 @@ public class ActivityDiagram3 extends UmlDiagram {
throws IOException {
// BUG42
// COMPRESSION
// TextBlock result = swinlanes;
TextBlock result = new TextBlockCompressed(swinlanes);
TextBlock result = swinlanes;
// result = new TextBlockCompressedOnY(CompressionMode.ON_Y, result);
// result = new TextBlockCompressedOnXorY(CompressionMode.ON_X, result);
result = new TextBlockCompressedOnXorY(CompressionMode.ON_Y, result);
result = new TextBlockRecentred(result);
final ISkinParam skinParam = getSkinParam();
result = new AnnotatedWorker(this, skinParam).addAdd(result);

View File

@ -39,7 +39,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.sourceforge.plantuml.AlignParam;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
@ -98,7 +98,7 @@ public abstract class AbstractFtile extends AbstractTextBlock implements Ftile {
}
public HorizontalAlignment arrowHorizontalAlignment() {
return skinParam.getHorizontalAlignment(AlignParam.ARROW_MESSAGE_ALIGN, null);
return skinParam.getHorizontalAlignment(AlignmentParam.arrowMessageAlignment, null);
}
private FtileGeometry cachedGeometry;

View File

@ -49,12 +49,12 @@ import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.ugraphic.CompressionTransform;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UPolygon;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.comp.CompressionTransform;
public class Snake implements UShape {

View File

@ -50,7 +50,7 @@ public class Swimlane implements SpecificBackcolorable {
private Display display;
private UTranslate translate = new UTranslate();
private double totalWidth;
private double actualWidth;
public Swimlane(String name) {
this.name = name;
@ -79,9 +79,9 @@ public class Swimlane implements SpecificBackcolorable {
return translate;
}
public final void setTranslateAndWidth(UTranslate translate, double totalWidth) {
public final void setTranslateAndWidth(UTranslate translate, double actualWidth) {
this.translate = translate;
this.totalWidth = totalWidth;
this.actualWidth = actualWidth;
}
public Colors getColors(ISkinParam skinParam) {
@ -96,8 +96,8 @@ public class Swimlane implements SpecificBackcolorable {
private Colors colors = Colors.empty();
public final double getTotalWidth() {
return totalWidth;
public final double getActualWidth() {
return actualWidth;
}
public void setColors(Colors colors) {

View File

@ -71,7 +71,6 @@ import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.svek.UGraphicForSnake;
import net.sourceforge.plantuml.ugraphic.LimitFinder;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.SlotSet;
import net.sourceforge.plantuml.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
@ -81,6 +80,7 @@ import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.comp.SlotSet;
import net.sourceforge.plantuml.utils.MathUtils;
public class Swimlanes extends AbstractTextBlock implements TextBlock {
@ -216,21 +216,20 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
if (back != null) {
final UGraphic background = ug.apply(new UChangeBackColor(back)).apply(new UChangeColor(back))
.apply(new UTranslate(x2, 0));
background.draw(new URectangle(swimlane.getTotalWidth(), dimensionFull.getHeight()
background.draw(new URectangle(swimlane.getActualWidth(), dimensionFull.getHeight()
+ titleHeightTranslate.getDy()));
}
final TextBlock swTitle = swimlane.getDisplay().create(getFontConfiguration(), HorizontalAlignment.LEFT,
skinParam);
final TextBlock swTitle = getTitle(swimlane);
final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth();
final double posTitle = x2 + (swimlane.getTotalWidth() - titleWidth) / 2;
final double posTitle = x2 + (swimlane.getActualWidth() - titleWidth) / 2;
swTitle.drawU(ug.apply(new UTranslate(posTitle, 0)));
drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
full.drawU(new UGraphicInterceptorOneSwimlane(ug, swimlane).apply(swimlane.getTranslate()).apply(
titleHeightTranslate));
x2 += swimlane.getTotalWidth();
x2 += swimlane.getActualWidth();
}
drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
@ -270,8 +269,7 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
final MinMax minMax = swimlane.getMinMax();
final double drawingWidth = minMax.getWidth() + 2 * separationMargin;
final TextBlock swTitle = swimlane.getDisplay().create(getFontConfiguration(), HorizontalAlignment.LEFT,
skinParam);
final TextBlock swTitle = getTitle(swimlane);
final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth();
final double totalWidth = MathUtils.max(swimlaneWidth, drawingWidth, titleWidth + 2 * separationMargin);
@ -286,8 +284,7 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
private UTranslate getTitleHeightTranslate(final StringBounder stringBounder) {
double titlesHeight = 0;
for (Swimlane swimlane : swimlanes) {
final TextBlock swTitle = swimlane.getDisplay().create(getFontConfiguration(), HorizontalAlignment.LEFT,
skinParam);
final TextBlock swTitle = getTitle(swimlane);
titlesHeight = Math.max(titlesHeight, swTitle.calculateDimension(stringBounder).getHeight());
}
@ -295,6 +292,11 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock {
return titleHeightTranslate;
}
private TextBlock getTitle(Swimlane swimlane) {
return swimlane.getDisplay().create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam,
skinParam.wrapWidth());
}
private void drawSeparation(UGraphic ug, double height) {
HtmlColor color = skinParam.getHtmlColor(ColorParam.swimlaneBorder, null, false);
if (color == null) {

View File

@ -0,0 +1,309 @@
/* ========================================================================
* 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;
import java.awt.geom.Dimension2D;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.Pragma;
import net.sourceforge.plantuml.activitydiagram3.Instruction;
import net.sourceforge.plantuml.activitydiagram3.InstructionList;
import net.sourceforge.plantuml.activitydiagram3.LinkRendering;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorAddNote;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorAddUrl;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorAssembly;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorCreateGroup;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorCreateParallel;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorIf;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorRepeat;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileFactoryDelegatorWhile;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.UGraphicInterceptorOneSwimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.VCompactFactory;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.UGraphicDelegator;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.svek.UGraphicForSnake;
import net.sourceforge.plantuml.ugraphic.LimitFinder;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.comp.SlotSet;
import net.sourceforge.plantuml.utils.MathUtils;
public class SwimlanesA extends AbstractTextBlock implements TextBlock {
protected final ISkinParam skinParam;;
private final Pragma pragma;
protected final List<Swimlane> swimlanes = new ArrayList<Swimlane>();
private Swimlane currentSwimlane = null;
private final Instruction root = new InstructionList();
private Instruction currentInstruction = root;
private LinkRendering nextLinkRenderer = LinkRendering.none();
public SwimlanesA(ISkinParam skinParam, Pragma pragma) {
this.skinParam = skinParam;
this.pragma = pragma;
}
private FtileFactory getFtileFactory(StringBounder stringBounder) {
FtileFactory factory = new VCompactFactory(skinParam, stringBounder);
factory = new FtileFactoryDelegatorAddUrl(factory);
factory = new FtileFactoryDelegatorAssembly(factory);
factory = new FtileFactoryDelegatorIf(factory, pragma);
factory = new FtileFactoryDelegatorWhile(factory);
factory = new FtileFactoryDelegatorRepeat(factory);
factory = new FtileFactoryDelegatorCreateParallel(factory);
// factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new
// FtileFactoryDelegatorCreateParallel1(factory));
factory = new FtileFactoryDelegatorAddNote(factory);
factory = new FtileFactoryDelegatorCreateGroup(factory);
return factory;
}
public void swimlane(String name, HtmlColor color, Display label) {
currentSwimlane = getOrCreate(name);
if (color != null) {
currentSwimlane.setSpecificColorTOBEREMOVED(ColorType.BACK, color);
}
if (Display.isNull(label) == false) {
currentSwimlane.setDisplay(label);
}
}
private Swimlane getOrCreate(String name) {
for (Swimlane s : swimlanes) {
if (s.getName().equals(name)) {
return s;
}
}
final Swimlane result = new Swimlane(name);
swimlanes.add(result);
return result;
}
class Cross extends UGraphicDelegator {
private Cross(UGraphic ug) {
super(ug);
}
@Override
public void draw(UShape shape) {
if (shape instanceof Ftile) {
final Ftile tile = (Ftile) shape;
tile.drawU(this);
} else if (shape instanceof Connection) {
final Connection connection = (Connection) shape;
final Ftile tile1 = connection.getFtile1();
final Ftile tile2 = connection.getFtile2();
if (tile1 == null || tile2 == null) {
return;
}
if (tile1.getSwimlaneOut() != tile2.getSwimlaneIn()) {
final ConnectionCross connectionCross = new ConnectionCross(connection);
connectionCross.drawU(getUg());
}
}
}
public UGraphic apply(UChange change) {
return new Cross(getUg().apply(change));
}
}
static protected final double separationMargin = 10;
private TextBlock full;
public void drawU(UGraphic ug) {
if (full == null) {
final FtileFactory factory = getFtileFactory(ug.getStringBounder());
full = root.createFtile(factory);
if (swimlanes.size() <= 1) {
// BUG42
full = new TextBlockInterceptorUDrawable(full);
}
}
ug = new UGraphicForSnake(ug);
if (swimlanes.size() <= 1) {
full.drawU(ug);
ug.flushUg();
return;
}
drawWhenSwimlanes(ug, full);
}
static private void printDebug(UGraphic ug, SlotSet slot, HtmlColor col, TextBlock full) {
slot.drawDebugX(ug.apply(new UChangeColor(col)).apply(new UChangeBackColor(col)),
full.calculateDimension(ug.getStringBounder()).getHeight());
}
protected void drawWhenSwimlanes(final UGraphic ug, TextBlock full) {
final StringBounder stringBounder = ug.getStringBounder();
final Dimension2D dimensionFull = full.calculateDimension(stringBounder);
computeSize(ug, full);
final UTranslate titleHeightTranslate = getTitleHeightTranslate(stringBounder);
double x2 = 0;
for (Swimlane swimlane : swimlanes) {
final HtmlColor back = swimlane.getColors(skinParam).getColor(ColorType.BACK);
if (back != null) {
final UGraphic background = ug.apply(new UChangeBackColor(back)).apply(new UChangeColor(back))
.apply(new UTranslate(x2, 0));
background.draw(new URectangle(swimlane.getActualWidth(), dimensionFull.getHeight()
+ titleHeightTranslate.getDy()));
}
full.drawU(new UGraphicInterceptorOneSwimlane(ug, swimlane).apply(swimlane.getTranslate()).apply(
titleHeightTranslate));
x2 += swimlane.getActualWidth();
}
final Cross cross = new Cross(ug.apply(titleHeightTranslate));
full.drawU(cross);
cross.flushUg();
}
protected UTranslate getTitleHeightTranslate(final StringBounder stringBounder) {
return new UTranslate();
}
private void computeDrawingWidths(UGraphic ug, TextBlock full) {
final StringBounder stringBounder = ug.getStringBounder();
for (Swimlane swimlane : swimlanes) {
final LimitFinder limitFinder = new LimitFinder(stringBounder, false);
final UGraphicInterceptorOneSwimlane interceptor = new UGraphicInterceptorOneSwimlane(new UGraphicForSnake(
limitFinder), swimlane);
full.drawU(interceptor);
interceptor.flushUg();
final MinMax minMax = limitFinder.getMinMax();
swimlane.setMinMax(minMax);
}
}
private void computeSize(UGraphic ug, TextBlock full) {
computeDrawingWidths(ug, full);
double x1 = 0;
double swimlaneWidth = skinParam.swimlaneWidth();
if (swimlaneWidth == ISkinParam.SWIMLANE_WIDTH_SAME) {
for (Swimlane swimlane : swimlanes) {
swimlaneWidth = Math.max(swimlaneWidth, rawDrawingWidth(swimlane));
}
}
for (Swimlane swimlane : swimlanes) {
final double swimlaneActualWidth = swimlaneActualWidth(ug.getStringBounder(), swimlaneWidth, swimlane);
final UTranslate translate = new UTranslate(x1 - swimlane.getMinMax().getMinX() + separationMargin
+ (swimlaneActualWidth - rawDrawingWidth(swimlane)) / 2.0, 0);
swimlane.setTranslateAndWidth(translate, swimlaneActualWidth);
x1 += swimlaneActualWidth;
}
}
protected double swimlaneActualWidth(StringBounder stringBounder, double swimlaneWidth, Swimlane swimlane) {
return MathUtils.max(swimlaneWidth, rawDrawingWidth(swimlane));
}
private double rawDrawingWidth(Swimlane swimlane) {
return swimlane.getMinMax().getWidth() + 2 * separationMargin;
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return getMinMax(stringBounder).getDimension();
}
public Instruction getCurrent() {
return currentInstruction;
}
public void setCurrent(Instruction current) {
this.currentInstruction = current;
}
public LinkRendering nextLinkRenderer() {
return nextLinkRenderer;
}
public void setNextLinkRenderer(LinkRendering link) {
if (link == null) {
throw new IllegalArgumentException();
}
this.nextLinkRenderer = link;
}
public Swimlane getCurrentSwimlane() {
return currentSwimlane;
}
private MinMax cachedMinMax;
@Override
public MinMax getMinMax(StringBounder stringBounder) {
if (cachedMinMax == null) {
cachedMinMax = TextBlockUtils.getMinMax(this, stringBounder);
}
return cachedMinMax;
}
}

View File

@ -0,0 +1,112 @@
/* ========================================================================
* 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;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineBreakStrategy;
import net.sourceforge.plantuml.Pragma;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.utils.MathUtils;
public class SwimlanesB extends SwimlanesA {
public SwimlanesB(ISkinParam skinParam, Pragma pragma) {
super(skinParam, pragma);
}
@Override
protected void drawWhenSwimlanes(UGraphic ug, TextBlock full) {
super.drawWhenSwimlanes(ug, full);
double x2 = 0;
final StringBounder stringBounder = ug.getStringBounder();
for (Swimlane swimlane : swimlanes) {
final TextBlock swTitle = getTitle(swimlane);
final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth();
final double posTitle = x2 + (swimlane.getActualWidth() - titleWidth) / 2;
swTitle.drawU(ug.apply(new UTranslate(posTitle, 0)));
x2 += swimlane.getActualWidth();
}
}
private TextBlock getTitle(Swimlane swimlane) {
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam, FontParam.SWIMLANE_TITLE, null);
LineBreakStrategy wrap = getWrap();
if (wrap.isAuto()) {
wrap = new LineBreakStrategy("" + ((int) swimlane.getActualWidth()));
}
return swimlane.getDisplay().create(fontConfiguration, HorizontalAlignment.LEFT, skinParam, wrap);
}
private LineBreakStrategy getWrap() {
LineBreakStrategy wrap = skinParam.swimlaneWrapTitleWidth();
if (wrap == LineBreakStrategy.NONE) {
wrap = skinParam.wrapWidth();
}
return wrap;
}
@Override
protected double swimlaneActualWidth(StringBounder stringBounder, double swimlaneWidth, Swimlane swimlane) {
final double m1 = super.swimlaneActualWidth(stringBounder, swimlaneWidth, swimlane);
if (getWrap().isAuto()) {
return m1;
}
final double titleWidth = getTitle(swimlane).calculateDimension(stringBounder).getWidth();
return MathUtils.max(m1, titleWidth + 2 * separationMargin);
}
@Override
protected UTranslate getTitleHeightTranslate(final StringBounder stringBounder) {
double titlesHeight = 0;
for (Swimlane swimlane : swimlanes) {
final TextBlock swTitle = getTitle(swimlane);
titlesHeight = Math.max(titlesHeight, swTitle.calculateDimension(stringBounder).getHeight());
}
return new UTranslate(0, titlesHeight);
}
}

View File

@ -0,0 +1,89 @@
/* ========================================================================
* 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;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.Pragma;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class SwimlanesC extends SwimlanesB {
public SwimlanesC(ISkinParam skinParam, Pragma pragma) {
super(skinParam, pragma);
}
@Override
protected void drawWhenSwimlanes(UGraphic ug, TextBlock full) {
super.drawWhenSwimlanes(ug, full);
double x2 = 0;
final StringBounder stringBounder = ug.getStringBounder();
final Dimension2D dimensionFull = full.calculateDimension(stringBounder);
final UTranslate titleHeightTranslate = getTitleHeightTranslate(stringBounder);
for (Swimlane swimlane : swimlanes) {
drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
x2 += swimlane.getActualWidth();
}
drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
}
private void drawSeparation(UGraphic ug, double height) {
HtmlColor color = skinParam.getHtmlColor(ColorParam.swimlaneBorder, null, false);
if (color == null) {
color = ColorParam.swimlaneBorder.getDefaultValue();
}
final UStroke thickness = Rose.getStroke(skinParam, LineParam.swimlaneBorder, 2);
ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height));
}
}

View File

@ -38,7 +38,7 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
import java.awt.geom.Dimension2D;
import java.util.Set;
import net.sourceforge.plantuml.AlignParam;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
@ -196,7 +196,7 @@ public class FtileGroup extends AbstractFtile {
final SymbolContext symbolContext = new SymbolContext(backColor, borderColor).withShadow(
skinParam().shadowing()).withStroke(stroke);
USymbol.FRAME.asBig(name, inner.skinParam().getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null),
USymbol.FRAME.asBig(name, inner.skinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null),
TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext).drawU(ug);
final Dimension2D dimHeaderNote = headerNote.calculateDimension(stringBounder);

View File

@ -250,7 +250,6 @@ class FtileWhile extends AbstractFtile {
final double x1 = p1.getX();
final double y1 = p1.getY();
final double x2 = p2.getX() + dimDiamond1.getWidth();
// final double y2 = p2.getY() + dimDiamond1.getOutY() / 2;
final double half = (dimDiamond1.getOutY() - dimDiamond1.getInY()) / 2;
final double y2 = p2.getY() + dimDiamond1.getInY() + half;
@ -268,8 +267,6 @@ class FtileWhile extends AbstractFtile {
ug.apply(new UTranslate(x1, y1bis)).draw(new UEmpty(5, Diamond.diamondHalfSize));
// ug = ug.apply(new UChangeColor(endInlinkColor)).apply(new UChangeBackColor(endInlinkColor));
// ug.apply(new UTranslate(xx, (y1 + y2) / 2)).draw(Arrows.asToUp());
}
public void drawTranslate(UGraphic ug, UTranslate translate1, UTranslate translate2) {
@ -281,12 +278,13 @@ class FtileWhile extends AbstractFtile {
final Point2D p1 = translate1.getTranslated(ap1);
final Point2D p2 = translate2.getTranslated(ap2);
final Dimension2D dimDiamond1 = diamond1.calculateDimension(stringBounder);
final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder);
final double x1 = p1.getX();
final double y1 = p1.getY();
final double x2 = p2.getX() + dimDiamond1.getWidth();
final double y2 = p2.getY() + dimDiamond1.getHeight() / 2;
final double half = (dimDiamond1.getOutY() - dimDiamond1.getInY()) / 2;
final double y2 = p2.getY() + dimDiamond1.getInY() + half;
snake.addPoint(x1, y1);
snake.addPoint(x1, y1 + Diamond.diamondHalfSize);
@ -402,8 +400,6 @@ class FtileWhile extends AbstractFtile {
snake.goUnmergeable(MergeStrategy.LIMITED);
ug.draw(snake);
// ug = ug.apply(new UChangeColor(afterEndwhileColor)).apply(new UChangeBackColor(afterEndwhileColor));
// ug.apply(new UTranslate(Diamond.diamondHalfSize, (y1 + y2) / 2)).draw(Arrows.asToDown());
final Snake snake2 = new Snake(arrowHorizontalAlignment(), afterEndwhileColor);
snake2.addPoint(Diamond.diamondHalfSize, y2);

View File

@ -125,7 +125,7 @@ public class FtileBox extends AbstractFtile {
final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT),
skinParam, CreoleMode.FULL).createSheet(label);
this.tb = new SheetBlock2(new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()), new MyStencil(), new UStroke(1));
this.tb = new SheetBlock2(new SheetBlock1(sheet, skinParam.wrapWidth(), skinParam.getPadding()), new MyStencil(), new UStroke(1));
this.print = label.toString();
}

View File

@ -33,31 +33,30 @@
*
*
*/
package net.sourceforge.plantuml.graphic;
package net.sourceforge.plantuml.code;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.CompressionTransform;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicCompress2;
import net.sourceforge.plantuml.StringUtils;
public class TextBlockCompressed2 extends AbstractTextBlock implements TextBlock {
public class ArobaseStringCompressor2 implements StringCompressor {
private final TextBlock textBlock;
private final CompressionTransform compressionTransform;
public TextBlockCompressed2(TextBlock textBlock, CompressionTransform compressionTransform) {
this.textBlock = textBlock;
this.compressionTransform = compressionTransform;
public String compress(String data) throws IOException {
return clean2(data);
}
public void drawU(final UGraphic ug) {
textBlock.drawU(new UGraphicCompress2(ug, compressionTransform));
public String decompress(String s) throws IOException {
return clean2(s);
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
final Dimension2D dim = textBlock.calculateDimension(stringBounder);
return new Dimension2DDouble(compressionTransform.transform(dim.getWidth()), dim.getHeight());
private String clean2(String s) {
s = s.replace("\0", "");
s = StringUtils.trin(s);
s = s.replace("\r", "").replaceAll("\n+$", "");
if (s.startsWith("@start")) {
return s;
}
return "@startuml\n" + s + "\n@enduml";
}
}

View File

@ -0,0 +1,109 @@
/* ========================================================================
* 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.code;
import java.io.IOException;
public class TranscoderSmart2 implements Transcoder {
// Legacy encoder
private final Transcoder oldOne = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
new CompressionHuffman());
private final Transcoder zlib = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
new CompressionZlib());
private final Transcoder brotli = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
new CompressionBrotli());
private final Transcoder zlibBase64 = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
new CompressionZlib());
private final Transcoder brotliBase64 = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
new CompressionBrotli());
private final Transcoder base64only = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
new CompressionNone());
private final Transcoder hexOnly = new TranscoderImpl(new AsciiEncoderHex(), new ArobaseStringCompressor2(),
new CompressionNone());
public String decode(String code) throws IOException {
// Work in progress
// See https://github.com/plantuml/plantuml/issues/117
// Two char headers
if (code.startsWith("0A")) {
return zlibBase64.decode(code.substring(2));
}
if (code.startsWith("0B")) {
return brotliBase64.decode(code.substring(2));
}
if (code.startsWith("0C")) {
return base64only.decode(code.substring(2));
}
if (code.startsWith("0D")) {
return hexOnly.decode(code.substring(2));
}
// Text prefix
// Just a wild try: use them only for testing
if (code.startsWith("-deflate-")) {
return zlibBase64.decode(code.substring("-deflate-".length()));
}
if (code.startsWith("-brotli-")) {
return brotliBase64.decode(code.substring("-brotli-".length()));
}
if (code.startsWith("-base64-")) {
return base64only.decode(code.substring("-base64-".length()));
}
if (code.startsWith("-hex-")) {
return hexOnly.decode(code.substring("-hex-".length()));
}
// Legacy decoding : you should not use it any more.
if (code.startsWith("0")) {
return brotli.decode(code.substring(1));
}
try {
return zlib.decode(code);
} catch (Exception ex) {
return oldOne.decode(code);
}
// return zlib.decode(code);
}
public String encode(String text) throws IOException {
// Right now, we still use the legacy encoding.
// This will be changed in the incoming months
return zlib.encode(text);
}
}

View File

@ -41,4 +41,8 @@ public class TranscoderUtil {
return new TranscoderSmart();
}
public static Transcoder getDefaultTranscoder2() {
return new TranscoderSmart2();
}
}

View File

@ -40,6 +40,8 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.Log;
public class Matcher2 {
private final static boolean INSTRUMENT = false;
@ -80,6 +82,7 @@ public class Matcher2 {
}
private static final Map<String, Long> durations = new HashMap<String, Long>();
private static long printed;
private static synchronized void addTime(String id, long duration) {
Long total = durations.get(id);
@ -88,12 +91,29 @@ public class Matcher2 {
}
total += duration;
durations.put(id, total);
if (total > 200) {
System.err.println("foo " + total + " " + id);
final String longest = getLongest();
if (longest == null) {
return;
}
if (durations.get(longest) > printed) {
Log.info("---------- Regex " + longest + " " + durations.get(longest) + "ms (" + durations.size() + ")");
printed = durations.get(longest);
}
}
private static String getLongest() {
long max = 0;
String result = null;
for (Map.Entry<String, Long> ent : durations.entrySet()) {
if (ent.getValue() > max) {
max = ent.getValue();
result = ent.getKey();
}
}
return result;
}
public String group(int n) {
final long now = System.currentTimeMillis();
try {

View File

@ -291,7 +291,7 @@ public class AtomText implements Atom {
}
public List<AtomText> getSplitted(StringBounder stringBounder, LineBreakStrategy maxWidthAsString) {
final double maxWidth = maxWidthAsString.getMathWidth();
final double maxWidth = maxWidthAsString.getMaxWidth();
final List<AtomText> result = new ArrayList<AtomText>();
final StringTokenizer st = new StringTokenizer(text, " ", true);
final StringBuilder currentLine = new StringBuilder();

View File

@ -58,7 +58,7 @@ public class Fission {
}
public List<Stripe> getSplitted(StringBounder stringBounder) {
final double valueMaxWidth = maxWidth.getMathWidth();
final double valueMaxWidth = maxWidth.getMaxWidth();
if (valueMaxWidth == 0) {
return Arrays.asList(stripe);
}

View File

@ -146,7 +146,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo
char separator = lineFirst ? '_' : 0;
TextBlock title = null;
List<Member> members = new ArrayList<Member>();
final LineBreakStrategy lineBreakStrategy = skinParam.wrapWidth();
// final LineBreakStrategy lineBreakStrategy = skinParam.wrapWidth();
for (ListIterator<String> it = rawBody.listIterator(); it.hasNext();) {
final String s = it.next();
if (manageHorizontalLine && isBlockSeparator(s)) {

View File

@ -95,7 +95,8 @@ public class Display implements Iterable<CharSequence> {
}
public boolean isWhite() {
return display.size() == 0 || (display.size() == 1 && display.get(0).toString().matches("\\s*"));
return display == null || display.size() == 0
|| (display.size() == 1 && display.get(0).toString().matches("\\s*"));
}
public static Display empty() {
@ -398,8 +399,8 @@ public class Display implements Iterable<CharSequence> {
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer, CreoleMode modeSimpleLine, LineBreakStrategy maxMessageSize) {
return create(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine,
null, null);
return create(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine, null,
null);
}
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,

View File

@ -40,6 +40,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import net.sourceforge.plantuml.version.Magic;
public class QBlock {
private final BigInteger big;
@ -59,6 +61,20 @@ public class QBlock {
return new QBlock(new BigInteger(block));
}
public static QBlock fromMagic(Magic magic) {
final byte[] buffer = magic.getBuffer();
final byte[] block = new byte[buffer.length + 1];
System.arraycopy(buffer, 0, block, 1, buffer.length);
final BigInteger big = new BigInteger(block);
return new QBlock(big);
}
public Magic toMagic() {
final Magic magic = new Magic();
magic.set(0, getData512());
return magic;
}
public QBlock(BigInteger number) {
this.big = number;
}
@ -68,13 +84,27 @@ public class QBlock {
return new QBlock(changed);
}
public byte[] getData() {
private byte[] getData512() {
final byte[] nb = big.toByteArray();
if (nb.length == 512) {
return nb;
}
final byte[] result = new byte[512];
if (nb.length < 512) {
System.arraycopy(nb, 0, result, 512 - nb.length, nb.length);
} else {
System.arraycopy(nb, nb.length - 512, result, 0, 512);
}
return result;
}
public byte[] getDataRaw() {
return big.toByteArray();
}
@Override
public String toString() {
return big.toByteArray().length + " " + big.toString();
return big.toByteArray().length + " " + big.toString(36);
}
public void write(OutputStream os, int size) throws IOException {

View File

@ -77,24 +77,24 @@ public class QBlocks {
}
}
public String encodeAscii() {
final StringBuilder sb = new StringBuilder();
final AsciiEncoder encoder = new AsciiEncoder();
for (QBlock rsa : all) {
sb.append(encoder.encode(rsa.getData()));
sb.append("!");
}
return sb.toString();
}
// public String encodeAscii() {
// final StringBuilder sb = new StringBuilder();
// final AsciiEncoder encoder = new AsciiEncoder();
// for (QBlock rsa : all) {
// sb.append(encoder.encode(rsa.getDataRaw()));
// sb.append("!");
// }
// return sb.toString();
// }
public static QBlocks descodeAscii(String s) {
final QBlocks result = new QBlocks();
final AsciiEncoder encoder = new AsciiEncoder();
for (String bl : s.split("!")) {
final BigInteger bigInteger = new BigInteger(encoder.decode(bl));
result.all.add(new QBlock(bigInteger));
}
return result;
}
// public static QBlocks descodeAscii(String s) {
// final QBlocks result = new QBlocks();
// final AsciiEncoder encoder = new AsciiEncoder();
// for (String bl : s.split("!")) {
// final BigInteger bigInteger = new BigInteger(encoder.decode(bl));
// result.all.add(new QBlock(bigInteger));
//
// }
// return result;
// }
}

View File

@ -35,7 +35,7 @@
*/
package net.sourceforge.plantuml.dedication;
class TurningBytes {
public class TurningBytes {
private final byte key[];
private int idx;

View File

@ -39,6 +39,9 @@ import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@ -89,6 +92,8 @@ public class CommandCreateElementMultilines extends CommandMultilines2<AbstractE
new RegexLeaf("[%s]*"), //
new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
new RegexLeaf("[%s]*"), //
ColorParser.exp1(), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("DESC", "as[%s]*[%g]([^%g]*)$"));
@ -100,6 +105,8 @@ public class CommandCreateElementMultilines extends CommandMultilines2<AbstractE
new RegexLeaf("[%s]*"), //
new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
new RegexLeaf("[%s]*"), //
ColorParser.exp1(), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("DESC", "\\[(.*)$"));
@ -155,6 +162,14 @@ public class CommandCreateElementMultilines extends CommandMultilines2<AbstractE
.getIHtmlColorSet()));
}
final String urlString = line0.get("URL", 0);
if (urlString != null) {
final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), ModeUrl.STRICT);
final Url url = urlBuilder.getUrl(urlString);
result.addUrl(url);
}
result.setSpecificColorTOBEREMOVED(ColorType.BACK,
diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)));

View File

@ -68,7 +68,7 @@ import net.sourceforge.plantuml.version.PSystemVersion;
public class PSystemDonors extends AbstractPSystem {
public static final String DONORS = "6vG70AmEU9ELAuNYZT_MZn6AGOgeeHNOWjgQuZoZA1P0SxnDhXdMoRgDdR45mND5SGKL8Az2C-THCiPX"
public static final String DONORS = "6wW70AmEU9ELAuNYZT_MZn6AGOgeeHNOWjgQuZoZA1P0SxnDhXdMoRgDdR45mND5SGKL8Az2C-THCiPX"
+ "qGYJjjcQVk6-VTu2CLLilsL2UtyTQ4BoLZ2km4tbpF_b0XiJv0R8GZti1NIZZNlZcZIc_NyMPXz_WHRm"
+ "DBfiMLGwq5cTNHLD233np1odb9A7OjnVaSBNZIs0buu7kTfO7U4RgRFlr0AQj6RJa9are5X6YaJpiT7Q"
+ "SO3jOnWuqM5T7JOGEvGuw1kC0-eRCKh65JJ8ZE9cRAZcdIS4J3YXmavyKPAQeuLaHXawq65jWGAyFnC4"
@ -81,7 +81,7 @@ public class PSystemDonors extends AbstractPSystem {
+ "F7JnJ-yMjT1vT_j7wljDVYMrr2F6esimz9PTrczjikXOG6prZ0Kk0tPgjnkJ0vNSGgSsd1KznGbOzxRE"
+ "mN4jWukcTREIdQcT73Dh1nskINx8qO1HqPr83hwsEoFFU1G5zYVddLZrKD-757yNK2o62PvIeMmZfEWA"
+ "czF9f76hPzmTl8zRcozKj_7DXIS4XH-RQDDoWzUd0FSK-a5J1v0wgrNoqiR42E1tVFq6FS-j3ZpAQ6cL"
+ "SNQv8PRIf_S8y1ioyae0";
+ "SNQv8PRIf_S8y1ioyahsjhkX10q0";
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.graphic;
import java.awt.Font;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.util.List;

View File

@ -36,7 +36,6 @@
package net.sourceforge.plantuml.graphic;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
@ -44,8 +43,6 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
import net.sourceforge.plantuml.FileSystem;
import net.sourceforge.plantuml.FileUtils;
import net.sourceforge.plantuml.StringUtils;

View File

@ -36,12 +36,11 @@
package net.sourceforge.plantuml.graphic;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.svek.RoundedContainer;
import net.sourceforge.plantuml.ugraphic.UStroke;
public class SkinParameter {

View File

@ -37,7 +37,6 @@ package net.sourceforge.plantuml.graphic;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;

View File

@ -57,7 +57,8 @@ public class TextBlockTitle implements TextBlock {
if (stringsToDisplay.size() == 1 && stringsToDisplay.get(0).length() == 0) {
throw new IllegalArgumentException();
}
textBlock = stringsToDisplay.create(font, HorizontalAlignment.CENTER, spriteContainer, LineBreakStrategy.NONE,
final LineBreakStrategy lineBreak = LineBreakStrategy.NONE;
textBlock = stringsToDisplay.create(font, HorizontalAlignment.CENTER, spriteContainer, lineBreak,
CreoleMode.FULL, null, null);
}

View File

@ -46,10 +46,10 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.posimo.Positionable;
import net.sourceforge.plantuml.posimo.PositionableImpl;

View File

@ -146,11 +146,11 @@ class USymbolDatabase extends USymbol {
drawDatabase(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing());
final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder());
final double posStereo = (width - dimStereo.getWidth()) / 2;
stereotype.drawU(ug.apply(new UTranslate(posStereo, 0)));
stereotype.drawU(ug.apply(new UTranslate(posStereo, 2 + 20)));
final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder());
final double posTitle = (width - dimTitle.getWidth()) / 2;
title.drawU(ug.apply(new UTranslate(posTitle, 21)));
title.drawU(ug.apply(new UTranslate(posTitle, 2 + 20 + dimStereo.getHeight())));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.graphic;
import gen.lib.dotgen.dotinit__c;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;

View File

@ -147,7 +147,7 @@ public class ScientificEquationSafe {
return new ImageDataSimple(image.getWidth(), image.getHeight());
}
if (fileFormat.getFileFormat() == FileFormat.SVG) {
os.write(getSvg(1, foregroundColor, backgroundColor).getSvg().getBytes());
os.write(getSvg(1, foregroundColor, backgroundColor).getSvg(true).getBytes());
return dimSvg;
}
return null;

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
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.HtmlColorSetSimple;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
@ -117,7 +118,7 @@ public class PostIt {
final FontConfiguration font2 = fontNote.toFont2(HtmlColorUtils.BLACK, true, HtmlColorUtils.BLUE, 8);
final ComponentRoseNote note = new ComponentRoseNote(
new SymbolContext(noteBackgroundColor, borderColor).withStroke(new UStroke()), font2, text, 0, 0,
new SpriteContainerEmpty(), 0);
new SpriteContainerEmpty(), 0, HorizontalAlignment.LEFT);
return note;
}
}

View File

@ -49,7 +49,6 @@ public class Define {
private final boolean emptyParentheses;
public Define(String key, List<String> lines, boolean emptyParentheses) {
this.signature = new DefineSignature(key);
this.emptyParentheses = emptyParentheses;
if (lines == null) {
this.definition = null;
@ -65,6 +64,7 @@ public class Define {
this.definition = sb.toString();
this.definitionQuoted = Matcher.quoteReplacement(definition);
}
this.signature = new DefineSignature(key, this.definitionQuoted);
}
@Override
@ -78,7 +78,7 @@ public class Define {
}
if (signature.isMethod()) {
for (Variables vars : signature.getVariationVariables()) {
line = vars.applyOn(line, signature.getFonctionName(), definitionQuoted);
line = vars.applyOn(line);
}
} else {
final String regex = "\\b" + signature.getKey() + "\\b" + (emptyParentheses ? "(\\(\\))?" : "");

View File

@ -43,24 +43,30 @@ import java.util.StringTokenizer;
public class DefineSignature {
private final String key;
private final String fctName;
private final Variables vars = new Variables();
private final String fonctionName;
private final List<Variables> variables = new ArrayList<Variables>();
public DefineSignature(String key) {
public DefineSignature(String key, String definitionQuoted) {
this.key = key;
final StringTokenizer st = new StringTokenizer(key, "(),");
this.fctName = st.nextToken().trim();
this.fonctionName = st.nextToken().trim();
final Variables master = new Variables(fonctionName, definitionQuoted);
while (st.hasMoreTokens()) {
final String var1 = st.nextToken().trim();
this.vars.add(new DefineVariable(var1));
master.add(new DefineVariable(var1));
}
final int count = master.countDefaultValue();
for (int i = 0; i <= count; i++) {
variables.add(master.removeSomeDefaultValues(i));
}
}
@Override
public String toString() {
return key + "/" + fctName + "/" + vars;
return key + "/" + fonctionName;
}
public boolean isMethod() {
@ -72,16 +78,7 @@ public class DefineSignature {
}
public List<Variables> getVariationVariables() {
final List<Variables> result = new ArrayList<Variables>();
final int count = vars.countDefaultValue();
for (int i = 0; i <= count; i++) {
result.add(vars.removeSomeDefaultValues(i));
}
return Collections.unmodifiableList(result);
}
public String getFonctionName() {
return fctName;
return Collections.unmodifiableList(variables);
}
}

View File

@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.version.Version;
class IfManager implements ReadLine {
class IfManager extends ReadLineInstrumented implements ReadLine {
protected static final Pattern2 ifdefPattern = MyPattern.cmpile("^[%s]*!if(n)?def[%s]+(.+)$");
protected static final Pattern2 ifcomparePattern = MyPattern
@ -61,7 +61,8 @@ class IfManager implements ReadLine {
this.source = source;
}
final public CharSequence2 readLine() throws IOException {
@Override
final CharSequence2 readLineInst() throws IOException {
if (child != null) {
final CharSequence2 s = child.readLine();
if (s != null) {
@ -117,7 +118,8 @@ class IfManager implements ReadLine {
return 0;
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
source.close();
}

View File

@ -37,192 +37,62 @@ package net.sourceforge.plantuml.preproc;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
import net.sourceforge.plantuml.DefinitionsContainer;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
import net.sourceforge.plantuml.Log;
public class Preprocessor implements ReadLine {
public class Preprocessor extends ReadLineInstrumented implements ReadLine {
private static final String END_DEFINE_LONG = "!enddefinelong";
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
private static final String ID_ARG = "\\s*[A-Za-z_][A-Za-z_0-9]*\\s*(?:=\\s*(?:\"[^\"]*\"|'[^']*')\\s*)?";
private static final String ARG = "(?:\\(" + ID_ARG + "(?:," + ID_ARG + ")*?\\))?";
private static final Pattern2 definePattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")"
+ "(?:[%s]+(.*))?$");
private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$");
private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$");
private static final Pattern2 definelongPattern = MyPattern.cmpile("^[%s]*!definelong[%s]+(" + ID + ARG + ")");
private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$");
private final Defines defines;
private final PreprocessorInclude rawSource;
private final ReadLineInsertable source;
private final PreprocessorInclude include;
private final SubPreprocessor subPreprocessor;
private final String description;
public Sub getSub(String blocname) {
return subPreprocessor.getSub(blocname);
}
// public Preprocessor(List<String> config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
// DefinitionsContainer definitionsContainer) {
//
// final ReadLine source2 = new IfManager(reader, defines);
// final ReadLineInsertable source3 = new ReadLineInsertable(source2);
// final ReadLine source4 = new PreprocessorDefine(defines, source3);
// this.include = new PreprocessorInclude(config, source4, defines, charset, newCurrentDir, definitionsContainer);
// this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, include);
// }
public Preprocessor(List<String> config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
DefinitionsContainer definitionsContainer) {
this.defines = defines;
this.defines.saveState();
this.rawSource = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
this.source = new ReadLineInsertable(new IfManager(rawSource, defines));
this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, new ReadLine() {
public void close() throws IOException {
Preprocessor.this.close();
}
public CharSequence2 readLine() throws IOException {
return readLineInternal();
}
});
this.description = reader.toString();
this.include = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
final ReadLine source2 = new IfManager(include, defines);
final ReadLineInsertable source3 = new ReadLineInsertable(source2);
final ReadLine source4 = new PreprocessorDefine(defines, source3);
this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, source4);
}
public CharSequence2 readLine() throws IOException {
@Override
CharSequence2 readLineInst() throws IOException {
return subPreprocessor.readLine();
}
private CharSequence2 readLineInternal() throws IOException {
final CharSequence2 s = source.readLine();
if (s == null) {
return null;
}
if (StartUtils.isArobaseStartDiagram(s)) {
this.defines.restoreState();
}
Matcher2 m = filenamePattern.matcher(s);
if (m.find()) {
return manageFilename(m);
}
m = definePattern.matcher(s);
if (m.find()) {
return manageDefine(m, s.toString().trim().endsWith("()"));
}
m = definelongPattern.matcher(s);
if (m.find()) {
return manageDefineLong(m, s.toString().trim().endsWith("()"));
}
m = undefPattern.matcher(s);
if (m.find()) {
return manageUndef(m);
}
if (ignoreDefineDuringSeveralLines > 0) {
ignoreDefineDuringSeveralLines--;
return s;
}
List<String> result = defines.applyDefines(s.toString2());
if (result.size() > 1) {
result = cleanEndDefineLong(result);
final List<String> inserted = cleanEndDefineLong(result.subList(1, result.size()));
ignoreDefineDuringSeveralLines = inserted.size();
source.insert(inserted, s.getLocation());
}
return new CharSequence2Impl(result.get(0), s.getLocation(), s.getPreprocessorError());
}
private List<String> cleanEndDefineLong(List<String> data) {
final List<String> result = new ArrayList<String>();
for (String s : data) {
final String clean = cleanEndDefineLong(s);
if (clean != null) {
result.add(clean);
}
}
return result;
}
private String cleanEndDefineLong(String s) {
if (s.trim().startsWith(END_DEFINE_LONG)) {
s = s.trim().substring(END_DEFINE_LONG.length());
if (s.length() == 0) {
return null;
}
}
return s;
}
private int ignoreDefineDuringSeveralLines = 0;
private CharSequence2 manageUndef(Matcher2 m) throws IOException {
defines.undefine(m.group(1));
return this.readLine();
}
private CharSequence2 manageDefineLong(Matcher2 m, boolean emptyParentheses) throws IOException {
final String group1 = m.group(1);
final List<String> def = new ArrayList<String>();
while (true) {
final CharSequence2 read = this.readLine();
if (read == null) {
return null;
}
if (enddefinelongPattern.matcher(read).find()) {
defines.define(group1, def, emptyParentheses);
return this.readLine();
}
def.add(read.toString2());
}
}
private CharSequence2 manageFilename(Matcher2 m) throws IOException {
final String group1 = m.group(1);
this.defines.overrideFilename(group1);
return this.readLine();
}
private CharSequence2 manageDefine(Matcher2 m, boolean emptyParentheses) throws IOException {
final String group1 = m.group(1);
final String group2 = m.group(2);
if (group2 == null) {
defines.define(group1, null, emptyParentheses);
} else {
final List<String> strings = defines.applyDefines(group2);
if (strings.size() > 1) {
defines.define(group1, strings, emptyParentheses);
} else {
final StringBuilder value = new StringBuilder(strings.get(0));
while (StringUtils.endsWithBackslash(value.toString())) {
value.setLength(value.length() - 1);
final CharSequence2 read = this.readLine();
value.append(read.toString2());
}
final List<String> li = new ArrayList<String>();
li.add(value.toString());
defines.define(group1, li, emptyParentheses);
}
}
return this.readLine();
}
public int getLineNumber() {
return rawSource.getLineNumber();
return include.getLineNumber();
}
public void close() throws IOException {
rawSource.close();
@Override
void closeInst() throws IOException {
// Log.info("Closing preprocessor of " + description);
include.close();
subPreprocessor.close();
}
public Set<FileWithSuffix> getFilesUsed() {
return Collections.unmodifiableSet(rawSource.getFilesUsedGlobal());
return Collections.unmodifiableSet(include.getFilesUsedGlobal());
}
}

View File

@ -0,0 +1,201 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.preproc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
public class PreprocessorDefine extends ReadLineInstrumented implements ReadLine {
private static final String END_DEFINE_LONG = "!enddefinelong";
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
private static final String ID_ARG = "\\s*[A-Za-z_][A-Za-z_0-9]*\\s*(?:=\\s*(?:\"[^\"]*\"|'[^']*')\\s*)?";
private static final String ARG = "(?:\\(" + ID_ARG + "(?:," + ID_ARG + ")*?\\))?";
private static final Pattern2 definePattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")"
+ "(?:[%s]+(.*))?$");
private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$");
private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$");
private static final Pattern2 definelongPattern = MyPattern.cmpile("^[%s]*!definelong[%s]+(" + ID + ARG + ")");
private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$");
private final Defines defines;
private final ReadLineInsertable source;
public PreprocessorDefine(Defines defines, ReadLineInsertable source) {
this.defines = defines;
this.defines.saveState();
this.source = source;
}
@Override
CharSequence2 readLineInst() throws IOException {
final CharSequence2 s = source.readLine();
if (s == null) {
return null;
}
if (StartUtils.isArobaseStartDiagram(s)) {
this.defines.restoreState();
}
Matcher2 m = filenamePattern.matcher(s);
if (m.find()) {
return manageFilename(m);
}
m = definePattern.matcher(s);
if (m.find()) {
return manageDefine(m, s.toString().trim().endsWith("()"));
}
m = definelongPattern.matcher(s);
if (m.find()) {
return manageDefineLong(m, s.toString().trim().endsWith("()"));
}
m = undefPattern.matcher(s);
if (m.find()) {
return manageUndef(m);
}
if (ignoreDefineDuringSeveralLines > 0) {
ignoreDefineDuringSeveralLines--;
return s;
}
List<String> result = defines.applyDefines(s.toString2());
if (result.size() > 1) {
result = cleanEndDefineLong(result);
final List<String> inserted = cleanEndDefineLong(result.subList(1, result.size()));
ignoreDefineDuringSeveralLines = inserted.size();
source.insert(inserted, s.getLocation());
}
return new CharSequence2Impl(result.get(0), s.getLocation(), s.getPreprocessorError());
}
private List<String> cleanEndDefineLong(List<String> data) {
final List<String> result = new ArrayList<String>();
for (String s : data) {
final String clean = cleanEndDefineLong(s);
if (clean != null) {
result.add(clean);
}
}
return result;
}
private String cleanEndDefineLong(String s) {
if (s.trim().startsWith(END_DEFINE_LONG)) {
s = s.trim().substring(END_DEFINE_LONG.length());
if (s.length() == 0) {
return null;
}
}
return s;
}
private int ignoreDefineDuringSeveralLines = 0;
private CharSequence2 manageUndef(Matcher2 m) throws IOException {
defines.undefine(m.group(1));
return this.readLine();
}
private CharSequence2 manageDefineLong(Matcher2 m, boolean emptyParentheses) throws IOException {
final String group1 = m.group(1);
final List<String> def = new ArrayList<String>();
while (true) {
final CharSequence2 read = this.readLine();
if (read == null) {
return null;
}
if (enddefinelongPattern.matcher(read).find()) {
defines.define(group1, def, emptyParentheses);
return this.readLine();
}
def.add(read.toString2());
}
}
private CharSequence2 manageFilename(Matcher2 m) throws IOException {
final String group1 = m.group(1);
this.defines.overrideFilename(group1);
return this.readLine();
}
private CharSequence2 manageDefine(Matcher2 m, boolean emptyParentheses) throws IOException {
final String group1 = m.group(1);
final String group2 = m.group(2);
if (group2 == null) {
defines.define(group1, null, emptyParentheses);
} else {
final List<String> strings = defines.applyDefines(group2);
if (strings.size() > 1) {
defines.define(group1, strings, emptyParentheses);
} else {
final StringBuilder value = new StringBuilder(strings.get(0));
while (StringUtils.endsWithBackslash(value.toString())) {
value.setLength(value.length() - 1);
final CharSequence2 read = this.readLine();
value.append(read.toString2());
}
final List<String> li = new ArrayList<String>();
li.add(value.toString());
defines.define(group1, li, emptyParentheses);
}
}
return this.readLine();
}
// public int getLineNumber() {
// return source.getLineNumber();
// }
@Override
void closeInst() throws IOException {
source.close();
}
}

View File

@ -63,7 +63,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
public class PreprocessorInclude implements ReadLine {
public class PreprocessorInclude extends ReadLineInstrumented implements ReadLine {
private static final Pattern2 includeDefPattern = MyPattern.cmpile("^[%s]*!includedef[%s]+[%g]?([^%g]+)[%g]?$");
private static final Pattern2 includePattern = MyPattern.cmpile("^[%s]*!include[%s]+[%g]?([^%g]+)[%g]?$");
@ -119,7 +119,8 @@ public class PreprocessorInclude implements ReadLine {
}
}
public CharSequence2 readLine() throws IOException {
@Override
CharSequence2 readLineInst() throws IOException {
final CharSequence2 result = readLineInternal();
if (result != null && StartUtils.isArobaseStartDiagram(result) && config.size() > 0) {
final List<String> empty = new ArrayList<String>();
@ -266,21 +267,13 @@ public class PreprocessorInclude implements ReadLine {
}
private InputStream getStdlibInputStream(String filename) {
return Stdlib.getResourceAsStream(filename);
}
private InputStream getStdlibInputStreamOld(String filename) {
if (filename.endsWith(".puml") == false) {
filename = filename + ".puml";
}
InputStream is = PreprocessorInclude.class.getResourceAsStream("/stdlib/" + filename);
if (is == null) {
is = PreprocessorInclude.class.getResourceAsStream("/stdlib/" + filename.toLowerCase());
}
return is;
final InputStream result = Stdlib.getResourceAsStream(filename);
// Log.info("Loading sdlib " + filename + " ok");
return result;
}
private ReadLine getReaderStdlibInclude(CharSequence2 s, String filename) {
Log.info("Loading sdlib " + filename);
InputStream is = getStdlibInputStream(filename);
if (is == null) {
return null;
@ -295,23 +288,12 @@ public class PreprocessorInclude implements ReadLine {
if (is == null) {
return null;
}
return ReadLineReader.create(new InputStreamReader(is), filename);
return ReadLineReader.create(new InputStreamReader(is), description);
} catch (IOException e) {
return new ReadLineSimple(s, e.toString());
}
}
// private ReadLine getReaderStdlibInclude2(CharSequence2 s, String filename) {
// InputStream is = DummyEmptyStdlibFile.class.getResourceAsStream(filename);
// if (is == null) {
// is = DummyEmptyStdlibFile.class.getResourceAsStream(filename.toLowerCase());
// }
// if (is == null) {
// return null;
// }
// return new ReadLineReader(new InputStreamReader(is), filename);
// }
private ReadLine getReaderInclude(CharSequence2 s, final File f, String suf) {
try {
if (StartDiagramExtractReader.containsStartDiagram(s, f, charset)) {
@ -352,7 +334,8 @@ public class PreprocessorInclude implements ReadLine {
return numLine;
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
restoreCurrentDir();
reader2.close();
}

View File

@ -0,0 +1,98 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2017, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.preproc;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.Log;
public abstract class ReadLineInstrumented implements ReadLine {
private static final boolean TRACE = false;
private static ConcurrentMap<Class, AtomicLong> durations = new ConcurrentHashMap<Class, AtomicLong>();
private static ConcurrentMap<Class, AtomicLong> maxes = new ConcurrentHashMap<Class, AtomicLong>();
private long current = 0;
private AtomicLong get(ConcurrentMap<Class, AtomicLong> source) {
AtomicLong result = source.get(getClass());
if (result == null) {
result = new AtomicLong();
source.put(getClass(), result);
}
return result;
}
public final CharSequence2 readLine() throws IOException {
if (TRACE == false) {
return readLineInst();
}
final long now = System.currentTimeMillis();
try {
return readLineInst();
} finally {
final long time = System.currentTimeMillis() - now;
current += time;
get(durations).addAndGet(time);
}
}
@Override
public String toString() {
return super.toString() + " current=" + current;
}
abstract CharSequence2 readLineInst() throws IOException;
public final void close() throws IOException {
if (TRACE) {
if (current > get(maxes).get()) {
get(maxes).set(current);
}
Log.info("DURATION::" + getClass() + " duration= " + get(durations).get() + " current=" + current + " max="
+ get(maxes).get());
}
closeInst();
}
abstract void closeInst() throws IOException;
}

View File

@ -40,7 +40,7 @@ import java.io.IOException;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
public class ReadLineQuoteComment implements ReadLine {
public class ReadLineQuoteComment extends ReadLineInstrumented implements ReadLine {
private final ReadLine raw;
private boolean longComment = false;
@ -49,11 +49,13 @@ public class ReadLineQuoteComment implements ReadLine {
this.raw = source;
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
raw.close();
}
public CharSequence2 readLine() throws IOException {
@Override
CharSequence2 readLineInst() throws IOException {
while (true) {
final CharSequence2 result = raw.readLine();
if (result == null) {

View File

@ -43,19 +43,28 @@ import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.LineLocationImpl;
import net.sourceforge.plantuml.Log;
public class ReadLineReader implements ReadLine {
public class ReadLineReader extends ReadLineInstrumented implements ReadLine {
// private static final int LIMIT = 850;
private final BufferedReader br;
private LineLocationImpl location;
private final String description;
private ReadLineReader(Reader reader, String description, LineLocation parent) {
if (description == null) {
description = "?";
}
br = new BufferedReader(reader);
location = new LineLocationImpl(description, parent);
this.br = new BufferedReader(reader);
this.location = new LineLocationImpl(description, parent);
this.description = description;
Log.info("Reading from " + description);
}
@Override
public String toString() {
return super.toString() + " " + description;
}
private ReadLineReader(Reader reader, String desc) {
@ -70,7 +79,8 @@ public class ReadLineReader implements ReadLine {
return new ReadLineReader(reader, description, parent);
}
public CharSequence2 readLine() throws IOException {
@Override
CharSequence2 readLineInst() throws IOException {
String s = br.readLine();
location = location.oneLineRead();
if (s == null) {
@ -99,7 +109,8 @@ public class ReadLineReader implements ReadLine {
return new CharSequence2Impl(s, location);
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
br.close();
}

View File

@ -76,9 +76,11 @@ public class Stdlib {
if (cached != null) {
final String cachedResult = cached.get();
if (cachedResult != null) {
// Log.info("Using cache for " + file);
return cachedResult;
}
}
Log.info("No cache for " + file);
final DataInputStream dataStream = getDataStream();
if (dataStream == null) {
return null;
@ -94,6 +96,7 @@ public class Stdlib {
while (true) {
final String filename = dataStream.readUTF();
if (filename.equals(SEPARATOR)) {
Log.info("Not found " + filename);
return null;
}
if (filename.equalsIgnoreCase(file)) {
@ -121,8 +124,10 @@ public class Stdlib {
}
final int width = Integer.parseInt(m.group(1));
final int height = Integer.parseInt(m.group(2));
final String sprite = readSprite(width, height, spriteStream);
if (found != null) {
if (found == null) {
skipSprite(width, height, spriteStream);
} else {
final String sprite = readSprite(width, height, spriteStream);
found.append(sprite);
found.append("}\n");
}
@ -141,9 +146,14 @@ public class Stdlib {
fillMap(info);
}
private String readSprite(int width, int height, InputStream inputStream) throws IOException {
final StringBuilder result = new StringBuilder();
private void skipSprite(int width, int height, InputStream inputStream) throws IOException {
final int nbLines = (height + 1) / 2;
inputStream.skip(nbLines * width);
}
private String readSprite(int width, int height, InputStream inputStream) throws IOException {
final int nbLines = (height + 1) / 2;
final StringBuilder result = new StringBuilder();
int line = 0;
for (int j = 0; j < nbLines; j++) {
final StringBuilder sb1 = new StringBuilder();

View File

@ -52,7 +52,7 @@ import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
public class SubPreprocessor implements ReadLine {
public class SubPreprocessor extends ReadLineInstrumented implements ReadLine {
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
@ -79,7 +79,8 @@ public class SubPreprocessor implements ReadLine {
this.definitionsContainer = definitionsContainer;
}
public CharSequence2 readLine() throws IOException {
@Override
CharSequence2 readLineInst() throws IOException {
if (includedSub != null) {
final CharSequence2 s = includedSub.readLine();
if (s != null) {
@ -176,7 +177,8 @@ public class SubPreprocessor implements ReadLine {
return result;
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
source.close();
}

View File

@ -44,21 +44,27 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
public class UncommentReadLine implements ReadLine {
public class UncommentReadLine extends ReadLineInstrumented implements ReadLine {
private static final Pattern2 unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN);
private final ReadLine raw;
private final Pattern2 start;
private final Pattern2 unpause;
// private final Pattern2 start;
private String headerToRemove;
private boolean paused;
public UncommentReadLine(ReadLine source) {
this.raw = source;
this.start = MyPattern.cmpile(StartUtils.START_PATTERN);
this.unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN);
// this.start = MyPattern.cmpile(StartUtils.START_PATTERN);
}
public CharSequence2 readLine() throws IOException {
@Override
public String toString() {
return "UncommentReadLine of " + raw;
}
@Override
CharSequence2 readLineInst() throws IOException {
final CharSequence2 result = raw.readLine();
if (result == null) {
@ -88,7 +94,8 @@ public class UncommentReadLine implements ReadLine {
return result;
}
public void close() throws IOException {
@Override
void closeInst() throws IOException {
this.raw.close();
}

View File

@ -38,10 +38,18 @@ package net.sourceforge.plantuml.preproc;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Variables {
private final List<DefineVariable> all = new ArrayList<DefineVariable>();
private final String fonctionName;
private final String definitionQuoted;
public Variables(String fonctionName, String definitionQuoted) {
this.fonctionName = fonctionName;
this.definitionQuoted = definitionQuoted;
}
public void add(DefineVariable var) {
this.all.add(var);
@ -61,7 +69,7 @@ public class Variables {
if (nb == 0) {
return this;
}
final Variables result = new Variables();
final Variables result = new Variables(fonctionName, definitionQuoted);
for (DefineVariable v : all) {
if (v.getDefaultValue() != null && nb > 0) {
result.add(v.removeDefault());
@ -76,36 +84,39 @@ public class Variables {
return result;
}
public String applyOn(String line, String fonctionName, String newValue) {
// System.err.println("KEY="+key);
// final StringTokenizer st = new StringTokenizer(key, "(),");
// final String fctName = st.nextToken();
final StringBuilder regex = new StringBuilder("\\b" + fonctionName + "\\(");
private String newValue;
private Pattern regex2;
final List<DefineVariable> variables = all;
boolean appended = false;
for (int j = 0; j < variables.size(); j++) {
final DefineVariable variable = variables.get(j);
final String varName = variable.getName();
final String var2 = "(##" + varName + "\\b)|(\\b" + varName + "##)|(\\b" + varName + "\\b)";
if (variable.getDefaultValue() == null) {
regex.append("(?:(?:\\s*\"([^\"]*)\"\\s*)|(?:\\s*'([^']*)'\\s*)|\\s*" + "((?:\\([^()]*\\)|[^,'\"])*?)"
+ ")");
final int i = 1 + 3 * j;
newValue = newValue.replaceAll(var2, "\\$" + i + "\\$" + (i + 1) + "\\$" + (i + 2));
regex.append(",");
appended = true;
} else {
newValue = newValue.replaceAll(var2, Matcher.quoteReplacement(variable.getDefaultValue()));
public String applyOn(String line) {
if (newValue == null) {
newValue = definitionQuoted;
final StringBuilder regex = new StringBuilder("\\b" + fonctionName + "\\(");
final List<DefineVariable> variables = all;
boolean appended = false;
for (int j = 0; j < variables.size(); j++) {
final DefineVariable variable = variables.get(j);
final String varName = variable.getName();
final String var2 = "(##" + varName + "\\b)|(\\b" + varName + "##)|(\\b" + varName + "\\b)";
if (variable.getDefaultValue() == null) {
regex.append("(?:(?:\\s*\"([^\"]*)\"\\s*)|(?:\\s*'([^']*)'\\s*)|\\s*"
+ "((?:\\([^()]*\\)|[^,'\"])*?)" + ")");
final int i = 1 + 3 * j;
newValue = newValue.replaceAll(var2, "\\$" + i + "\\$" + (i + 1) + "\\$" + (i + 2));
regex.append(",");
appended = true;
} else {
newValue = newValue.replaceAll(var2, Matcher.quoteReplacement(variable.getDefaultValue()));
}
}
if (appended == true) {
regex.setLength(regex.length() - 1);
}
regex.append("\\)");
regex2 = Pattern.compile(regex.toString());
}
if (appended == true) {
regex.setLength(regex.length() - 1);
}
regex.append("\\)");
// System.err.println("regex=" + regex);
// System.err.println("newValue=" + newValue);
line = line.replaceAll(regex.toString(), newValue);
// line = line.replaceAll(regex.toString(), newValue);
line = regex2.matcher(line).replaceAll(newValue);
return line;
}

View File

@ -48,7 +48,7 @@ public class SubjectTask implements SubjectPattern {
public Collection<VerbPattern> getVerbs() {
return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
new VerbHappens(), new VerbEnds(), new VerbIsColored());
new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored());
}
public IRegex toRegex() {

View File

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

View File

@ -47,6 +47,7 @@ import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.ScaleSimple;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.WithSprite;
import net.sourceforge.plantuml.api.ImageDataSimple;
@ -108,7 +109,12 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite {
final Element salt = createElement(manageSprite());
final Dimension2D size = salt.getPreferredDimension(fileFormat.getDefaultStringBounder(), 0, 0);
final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, null,
double scale = 1;
if (getScale() != null) {
scale = getScale().getScale(size.getWidth(), size.getHeight());
}
final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), scale, HtmlColorUtils.WHITE, null,
null, 5, 5, null, false);
builder.setUDrawable(new UDrawable() {
@ -146,6 +152,10 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite {
// System.err.println("skipping " + s);
} else if (s.startsWith("skinparam ")) {
// System.err.println("skipping " + s);
} else if (s.startsWith("scale ")) {
final Double scale = Double.parseDouble(s.substring("scale ".length()));
this.setScale(new ScaleSimple(scale));
// System.err.println("skipping " + s);
} else if (s.startsWith("sprite $")) {
BlocLines bloc = BlocLines.single(s);
do {

View File

@ -280,7 +280,10 @@ public class SequenceDiagram extends UmlDiagram {
p.incInitialLife(new SymbolContext(backcolor, linecolor));
return null;
}
return "Only activate command can occur before message are send";
if (p.getInitialLife() == 0) {
return "You cannot deactivate here";
}
return null;
}
if (lifeEventType == LifeEventType.ACTIVATE && lastEventWithDeactivate instanceof Message) {
activationState.push((Message) lastEventWithDeactivate);

View File

@ -41,15 +41,19 @@ import java.io.OutputStream;
import java.io.PrintStream;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.asciiart.TextSkin;
import net.sourceforge.plantuml.asciiart.TextStringBounder;
import net.sourceforge.plantuml.asciiart.UmlCharArea;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.sequencediagram.Event;
import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.Skin;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt;
public class SequenceDiagramTxtMaker implements FileMaker {
@ -75,18 +79,18 @@ public class SequenceDiagramTxtMaker implements FileMaker {
}
for (Event ev : sequenceDiagram.events()) {
initializer.addEvent(ev);
// if (ev instanceof Message) {
// // TODO mieux faire
// final Message m = (Message) ev;
// for (LifeEvent lifeEvent : m.getLiveEvents()) {
// if (lifeEvent.getType() == LifeEventType.DESTROY
// /*
// * || lifeEvent.getType() == LifeEventType.CREATE
// */) {
// initializer.addEvent(lifeEvent);
// }
// }
// }
// if (ev instanceof Message) {
// // TODO mieux faire
// final Message m = (Message) ev;
// for (LifeEvent lifeEvent : m.getLiveEvents()) {
// if (lifeEvent.getType() == LifeEventType.DESTROY
// /*
// * || lifeEvent.getType() == LifeEventType.CREATE
// */) {
// initializer.addEvent(lifeEvent);
// }
// }
// }
}
drawableSet = initializer.createDrawableSet(dummyStringBounder);
// final List<Newpage> newpages = new ArrayList<Newpage>();
@ -100,10 +104,24 @@ public class SequenceDiagramTxtMaker implements FileMaker {
final double tailHeight = drawableSet.getTailHeight(dummyStringBounder, diagram.isShowFootbox());
final double newpage2 = fullDimension.getHeight() - (diagram.isShowFootbox() ? tailHeight : 0) - headerHeight;
final Page page = new Page(headerHeight, 0, newpage2, tailHeight, 0, null);
//drawableSet.drawU_REMOVEDME_4243(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
drawableSet.drawU22(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
}
// drawableSet.drawU_REMOVEDME_4243(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
final Display title = diagram.getTitle().getDisplay();
final UGraphicTxt ug2;
if (title.isWhite()) {
ug2 = ug;
} else {
ug2 = (UGraphicTxt) ug.apply(new UTranslate(0, title.as().size() + 1));
}
drawableSet.drawU22(ug2, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
if (title.isWhite() == false) {
final int widthTitle = StringUtils.getWcWidth(title);
final UmlCharArea charArea = ug.getCharArea();
charArea.drawStringsLR(title.as(), (int) ((fullDimension.getWidth() - widthTitle) / 2), 0);
}
}
public ImageData createOne(OutputStream os, int index, boolean isWithMetadata) throws IOException {
if (fileFormat == FileFormat.UTXT) {

View File

@ -60,7 +60,7 @@ public class LifeEventTile implements TileWithUpdateStairs {
private final ISkinParam skinParam;
public void updateStairs(StringBounder stringBounder, double y) {
System.err.println("LifeEventTile::updateStairs " + lifeEvent + " " + livingSpace.getParticipant() + " y=" + y);
// System.err.println("LifeEventTile::updateStairs " + lifeEvent + " " + livingSpace.getParticipant() + " y=" + y);
livingSpace.addStepForLivebox(getEvent(), y);
}

View File

@ -148,8 +148,9 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
public void drawU(UGraphic ug) {
ug = ug.apply(min1translate);
englobers.drawEnglobers(goDownForEnglobers(ug), main.calculateDimension(stringBounder).getHeight()
+ heightEnglober1 + heightEnglober2 / 2, new SimpleContext2D(true));
englobers.drawEnglobers(goDownAndCenterForEnglobers(ug), main.calculateDimension(stringBounder)
.getHeight() + heightEnglober1 + heightEnglober2 / 2, new SimpleContext2D(true));
printAligned(ug, diagram.getFooterOrHeaderTeoz(FontParam.HEADER).getHorizontalAlignment(), header);
ug = goDown(ug, header);
@ -182,13 +183,14 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
}
private UGraphic goDownForEnglobers(UGraphic ug) {
private UGraphic goDownAndCenterForEnglobers(UGraphic ug) {
ug = goDown(ug, title);
ug = goDown(ug, header);
if (diagram.getLegend().getVerticalAlignment() == VerticalAlignment.TOP) {
ug = goDown(ug, legend);
}
return ug;
final double dx = (dimTotal.getWidth() - main.calculateDimension(stringBounder).getWidth()) / 2;
return ug.apply(new UTranslate(dx, 0));
}
private UGraphic goDown(UGraphic ug, TextBlock size) {

View File

@ -84,7 +84,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
if (strings.size() == 1 && strings.get(0).length() == 0) {
textBlock = new TextBlockEmpty();
} else if (enhanced) {
textBlock = new BodyEnhanced2(strings, FontParam.NOTE, spriteContainer, HorizontalAlignment.LEFT, font,
textBlock = new BodyEnhanced2(strings, FontParam.NOTE, spriteContainer, horizontalAlignment, font,
maxMessageSize);
} else {
textBlock = strings.create(font, horizontalAlignment, spriteContainer, maxMessageSize, CreoleMode.FULL,

View File

@ -60,9 +60,9 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements
private final double roundCorner;
public ComponentRoseNote(SymbolContext symbolContext, FontConfiguration font, Display strings, double paddingX,
double paddingY, ISkinSimple spriteContainer, double roundCorner) {
super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.LEFT, 6, 15, 5, spriteContainer, true, null,
null);
double paddingY, ISkinSimple spriteContainer, double roundCorner, HorizontalAlignment horizontalAlignment) {
super(LineBreakStrategy.NONE, strings, font, horizontalAlignment,
horizontalAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null);
this.roundCorner = roundCorner;
this.paddingX = paddingX;
this.paddingY = paddingY;

View File

@ -35,7 +35,7 @@
*/
package net.sourceforge.plantuml.skin.rose;
import net.sourceforge.plantuml.AlignParam;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
@ -100,9 +100,9 @@ public class Rose implements Skin {
config, param, param.maxMessageSize(), param.strictUmlStyle() == false);
}
final HorizontalAlignment messageHorizontalAlignment = param.getHorizontalAlignment(
AlignParam.SEQUENCE_MESSAGE_ALIGN, config.getArrowDirection());
AlignmentParam.sequenceMessageAlignment, config.getArrowDirection());
final HorizontalAlignment textHorizontalAlignment = param.getHorizontalAlignment(
AlignParam.SEQUENCE_MESSAGETEXT_ALIGN, config.getArrowDirection());
AlignmentParam.sequenceMessageTextAlignment, config.getArrowDirection());
return new ComponentRoseArrow(sequenceArrow, getUFont2(param, FontParam.ARROW), stringsToDisplay, config,
messageHorizontalAlignment, param, textHorizontalAlignment, param.maxMessageSize(),
param.strictUmlStyle() == false, param.responseMessageBelowArrow());
@ -198,8 +198,9 @@ public class Rose implements Skin {
FontParam.DATABASE_STEREOTYPE));
}
if (type == ComponentType.NOTE) {
final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null);
return new ComponentRoseNote(getSymbolContext(param, ColorParam.noteBorder), getUFont2(param,
FontParam.NOTE), stringsToDisplay, paddingX, paddingY, param, roundCorner);
FontParam.NOTE), stringsToDisplay, paddingX, paddingY, param, roundCorner, alignment);
}
if (type == ComponentType.NOTE_HEXAGONAL) {
return new ComponentRoseNoteHexagonal(getSymbolContext(param, ColorParam.noteBorder), getUFont2(param,
@ -258,7 +259,7 @@ public class Rose implements Skin {
if (type == ComponentType.REFERENCE) {
return new ComponentRoseReference(getUFont2(param, FontParam.SEQUENCE_REFERENCE), getSymbolContext(param,
ColorParam.sequenceReferenceBorder), bigFont, stringsToDisplay, param.getHorizontalAlignment(
AlignParam.SEQUENCE_REFERENCE_ALIGN, null), param, getHtmlColor(param,
AlignmentParam.sequenceReferenceAlignment, null), param, getHtmlColor(param,
ColorParam.sequenceReferenceBackground));
}
// if (type == ComponentType.TITLE) {

View File

@ -48,7 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.plantuml.AlignParam;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
@ -365,7 +365,7 @@ public class Cluster implements Moveable {
final ClusterDecoration decoration = new ClusterDecoration(style, group.getUSymbol(), ztitle, zstereo,
minX, minY, maxX, maxY, stroke2);
decoration.drawU(ug, back, borderColor, shadowing, roundCorner,
skinParam2.getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null));
skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null));
return;
}
final URectangle rect = new URectangle(maxX - minX, maxY - minY);
@ -742,7 +742,7 @@ public class Cluster implements Moveable {
sblabel.append(">");
label = sblabel.toString();
final HorizontalAlignment align = skinParam
.getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null);
.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null);
sb.append("labeljust=\"" + align.getGraphVizValue() + "\";");
} else {
label = "\"\"";

View File

@ -184,7 +184,7 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
if (flashCode != null) {
final double h = graphicStrings.calculateDimension(ug.getStringBounder()).getHeight();
ug = ug.apply(new UTranslate(0, h));
ug.draw(new UImage(flashCode));
ug.draw(new UImage(flashCode).scaleNearestNeighbor(3));
}
}

View File

@ -51,6 +51,11 @@ public class UGraphicForSnake extends UGraphicDelegator {
private final double dy;
private final List<PendingSnake> snakes;
@Override
public String toString() {
return super.toString() + " " + getUg();
}
public UTranslate getTranslation() {
return new UTranslate(dx, dy);
}

View File

@ -37,7 +37,7 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.AlignParam;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
@ -130,7 +130,7 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
decoration.drawU(ug, back, SkinParamUtils.getColor(getSkinParam(), ColorParam.packageBorder, getStereo()),
getSkinParam().shadowing(), roundCorner,
getSkinParam().getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null));
getSkinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null));
if (url != null) {
ug.closeAction();

View File

@ -743,11 +743,11 @@ public class SvgGraphics {
private String manageScale(SvgString svg) {
final double svgScale = svg.getScale();
if (svgScale * scale == 1) {
return svg.getSvg();
return svg.getSvg(false);
}
final String s1 = "\\<g\\b";
final String s2 = "<g transform=\"scale(" + format(svgScale) + "," + format(svgScale) + ")\" ";
return svg.getSvg().replaceFirst(s1, s2);
return svg.getSvg(false).replaceFirst(s1, s2);
}
private String toBase64(BufferedImage image) throws IOException {

View File

@ -42,6 +42,7 @@ import java.util.TreeSet;
import net.sourceforge.plantuml.SkinParam;
import net.sourceforge.plantuml.graphic.HtmlColorSetSimple;
import net.sourceforge.plantuml.utils.Cypher;
public class LanguageDescriptor {
@ -165,6 +166,26 @@ public class LanguageDescriptor {
preproc.add("!enddefinelong");
}
public Cypher getCypher() {
final Cypher cypher = new Cypher();
for (String s : type) {
cypher.addException(s);
}
for (String s : keyword) {
cypher.addException(s.replace("@", ""));
}
for (String s : preproc) {
cypher.addException(s.substring(1));
}
for (String s : SkinParam.getPossibleValues()) {
cypher.addException(s);
}
for (String s : new HtmlColorSetSimple().names()) {
cypher.addException(s);
}
return cypher;
}
public void print(PrintStream ps) {
print(ps, "type", type);
print(ps, "keyword", keyword);
@ -175,7 +196,7 @@ public class LanguageDescriptor {
}
private static void print(PrintStream ps, String name, Collection<String> data) {
ps.println(";"+name);
ps.println(";" + name);
ps.println(";" + data.size());
for (String k : data) {
ps.println(k);

View File

@ -48,7 +48,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import javax.imageio.ImageIO;

View File

@ -55,6 +55,7 @@ import javax.swing.ImageIcon;
import net.sourceforge.plantuml.AnimatedGifEncoder;
import net.sourceforge.plantuml.CMapData;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.EmptyImageBuilder;
import net.sourceforge.plantuml.FileFormat;
@ -63,7 +64,6 @@ import net.sourceforge.plantuml.FileUtils;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.anim.AffineTransformation;

View File

@ -1,156 +0,0 @@
/* ========================================================================
* 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.ugraphic;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.graphic.StringBounder;
public class SlotFinderX implements UGraphic {
public boolean matchesProperty(String propertyName) {
return false;
}
public double dpiFactor() {
return 1;
}
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
return new SlotFinderX(stringBounder, xslot, yslot, translate.compose((UTranslate) change));
} else if (change instanceof UStroke) {
return new SlotFinderX(this);
} else if (change instanceof UChangeBackColor) {
return new SlotFinderX(this);
} else if (change instanceof UChangeColor) {
return new SlotFinderX(this);
}
throw new UnsupportedOperationException();
}
private final SlotSet xslot;
private final SlotSet yslot;
private final StringBounder stringBounder;
private final UTranslate translate;
public SlotFinderX(StringBounder stringBounder) {
this(stringBounder, new SlotSet(), new SlotSet(), new UTranslate());
}
private SlotFinderX(StringBounder stringBounder, SlotSet xslot, SlotSet yslot, UTranslate translate) {
this.stringBounder = stringBounder;
this.xslot = xslot;
this.yslot = yslot;
this.translate = translate;
}
private SlotFinderX(SlotFinderX other) {
this(other.stringBounder, other.xslot, other.yslot, other.translate);
}
public StringBounder getStringBounder() {
return stringBounder;
}
public UParam getParam() {
return new UParamNull();
}
public void draw(UShape shape) {
final double x = translate.getDx();
final double y = translate.getDy();
if (shape instanceof URectangle) {
drawRectangle(x, y, (URectangle) shape);
} else if (shape instanceof UPolygon) {
drawPolygon(x, y, (UPolygon) shape);
} else if (shape instanceof UEllipse) {
drawEllipse(x, y, (UEllipse) shape);
} else if (shape instanceof UText) {
drawText(x, y, (UText) shape);
} else if (shape instanceof UEmpty) {
drawEmpty(x, y, (UEmpty) shape);
}
}
private void drawEmpty(double x, double y, UEmpty shape) {
xslot.addSlot(x, x + shape.getWidth());
yslot.addSlot(y, y + shape.getHeight());
}
private void drawText(double x, double y, UText shape) {
final TextLimitFinder finder = new TextLimitFinder(stringBounder, false);
finder.apply(new UTranslate(x, y)).draw(shape);
xslot.addSlot(finder.getMinX(), finder.getMaxX());
yslot.addSlot(finder.getMinY(), finder.getMaxY());
}
private void drawEllipse(double x, double y, UEllipse shape) {
xslot.addSlot(x, x + shape.getWidth());
yslot.addSlot(y, y + shape.getHeight());
}
private void drawPolygon(double x, double y, UPolygon shape) {
xslot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
yslot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
}
private void drawRectangle(double x, double y, URectangle shape) {
xslot.addSlot(x, x + shape.getWidth());
yslot.addSlot(y, y + shape.getHeight());
}
public ColorMapper getColorMapper() {
return new ColorMapperIdentity();
}
public void startUrl(Url url) {
}
public void closeAction() {
}
public SlotSet getXSlotSet() {
return xslot;
}
public SlotSet getYSlotSet() {
return yslot;
}
public void flushUg() {
}
}

View File

@ -1,98 +0,0 @@
/* ========================================================================
* 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.ugraphic;
import net.sourceforge.plantuml.activitydiagram3.ftile.Snake;
import net.sourceforge.plantuml.graphic.UGraphicDelegator;
public class UGraphicCompress2 extends UGraphicDelegator {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
return new UGraphicCompress2(getUg(), compressionTransform, translate.compose((UTranslate) change));
} else if (change instanceof UStroke || change instanceof UChangeBackColor || change instanceof UChangeColor) {
return new UGraphicCompress2(getUg().apply(change), compressionTransform, translate);
}
throw new UnsupportedOperationException();
}
private final CompressionTransform compressionTransform;
private final UTranslate translate;
public UGraphicCompress2(UGraphic ug, CompressionTransform compressionTransform) {
this(ug, compressionTransform, new UTranslate());
}
private UGraphicCompress2(UGraphic ug, CompressionTransform compressionTransform, UTranslate translate) {
super(ug);
this.compressionTransform = compressionTransform;
this.translate = translate;
}
public void draw(UShape shape) {
final double x = translate.getDx();
final double y = translate.getDy();
if (shape instanceof ULine) {
drawLine(x, y, (ULine) shape);
} else if (shape instanceof Snake) {
drawSnake(x, y, (Snake) shape);
} else {
getUg().apply(new UTranslate(ct(x), y)).draw(shape);
}
}
private void drawSnake(double x, double y, Snake shape) {
final Snake transformed = shape.translate(new UTranslate(x, y)).transformX(compressionTransform);
getUg().draw(transformed);
}
private void drawLine(double x, double y, ULine shape) {
drawLine(ct(x), y, ct(x + shape.getDX()), y + shape.getDY());
}
private double ct(double v) {
return compressionTransform.transform(v);
}
private void drawLine(double x1, double y1, double x2, double y2) {
final double xmin = Math.min(x1, x2);
final double xmax = Math.max(x1, x2);
final double ymin = Math.min(y1, y2);
final double ymax = Math.max(y1, y2);
getUg().apply(new UTranslate(xmin, ymin)).draw(new ULine(xmax - xmin, ymax - ymin));
}
}

View File

@ -43,32 +43,19 @@ public class UImage implements UShape {
private final BufferedImage image;
// public final double getScale() {
// return scale;
// }
public UImage(BufferedImage image) {
this.image = image;
}
// public UImage(BufferedImage before, double scale) {
// this.image = before;
// this.scale = scale;
// // if (scale == 1) {
// // this.image = before;
// // return;
// // }
//
// // final int w = (int) Math.round(before.getWidth() * scale);
// // final int h = (int) Math.round(before.getHeight() * scale);
// // final BufferedImage after = new BufferedImage(w, h, before.getType());
// // final AffineTransform at = new AffineTransform();
// // at.scale(scale, scale);
// // final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
// // this.image = scaleOp.filter(before, after);
// }
public UImage scale(double scale) {
return scale(scale, AffineTransformOp.TYPE_BILINEAR);
}
public UImage scaleNearestNeighbor(double scale) {
return scale(scale, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
}
private UImage scale(double scale, final int type) {
if (scale == 1) {
return this;
}
@ -77,7 +64,7 @@ public class UImage implements UShape {
final BufferedImage after = new BufferedImage(w, h, image.getType());
final AffineTransform at = new AffineTransform();
at.scale(scale, scale);
final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
final AffineTransformOp scaleOp = new AffineTransformOp(at, type);
return new UImage(scaleOp.filter(image, after));
}
@ -93,8 +80,4 @@ public class UImage implements UShape {
return image.getHeight() - 1;
}
// public UShape getScaled(double scale) {
// return scale(scale);
// }
}

View File

@ -44,13 +44,20 @@ public class URectangle extends AbstractShadowable implements Scalable, UShapeSi
private final double ry;
private final String comment;
public URectangle withWidth(double newHeight) {
public URectangle withHeight(double newHeight) {
final URectangle result = new URectangle(width, newHeight, rx, ry, comment);
result.ignoreForCompression = this.ignoreForCompression;
result.setDeltaShadow(this.getDeltaShadow());
return result;
}
public URectangle withWidth(double newWidth) {
final URectangle result = new URectangle(newWidth, height, rx, ry, comment);
result.ignoreForCompression = this.ignoreForCompression;
result.setDeltaShadow(this.getDeltaShadow());
return result;
}
public UShape getScaled(double scale) {
if (scale == 1) {
return this;

View File

@ -0,0 +1,41 @@
/* ========================================================================
* 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.ugraphic.comp;
public enum CompressionMode {
ON_X, ON_Y
}

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.ugraphic;
package net.sourceforge.plantuml.ugraphic.comp;
import java.util.List;

View File

@ -33,7 +33,7 @@
*
*
*/
package net.sourceforge.plantuml.ugraphic;
package net.sourceforge.plantuml.ugraphic.comp;
public class Slot implements Comparable<Slot> {

View File

@ -33,10 +33,28 @@
*
*
*/
package net.sourceforge.plantuml.ugraphic;
package net.sourceforge.plantuml.ugraphic.comp;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.ugraphic.ColorMapper;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
import net.sourceforge.plantuml.ugraphic.TextLimitFinder;
import net.sourceforge.plantuml.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UEmpty;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UParam;
import net.sourceforge.plantuml.ugraphic.UParamNull;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.UPolygon;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UText;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class SlotFinder implements UGraphic {
@ -50,7 +68,7 @@ public class SlotFinder implements UGraphic {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
return new SlotFinder(stringBounder, yslot, translate.compose((UTranslate) change));
return new SlotFinder(mode, stringBounder, slot, translate.compose((UTranslate) change));
} else if (change instanceof UStroke) {
return new SlotFinder(this);
} else if (change instanceof UChangeBackColor) {
@ -61,22 +79,25 @@ public class SlotFinder implements UGraphic {
throw new UnsupportedOperationException();
}
private final SlotSet yslot;
private final SlotSet slot;
private final StringBounder stringBounder;
private final UTranslate translate;
private final CompressionMode mode;
public SlotFinder(StringBounder stringBounder) {
this(stringBounder, new SlotSet(), new UTranslate());
public SlotFinder(CompressionMode mode, StringBounder stringBounder) {
this(mode, stringBounder, new SlotSet(), new UTranslate());
}
private SlotFinder(StringBounder stringBounder, SlotSet yslot, UTranslate translate) {
private SlotFinder(CompressionMode mode, StringBounder stringBounder, SlotSet slot, UTranslate translate) {
this.stringBounder = stringBounder;
this.yslot = yslot;
this.slot = slot;
this.translate = translate;
this.mode = mode;
}
private SlotFinder(SlotFinder other) {
this(other.stringBounder, other.yslot, other.translate);
this(other.mode, other.stringBounder, other.slot, other.translate);
}
public StringBounder getStringBounder() {
@ -92,12 +113,19 @@ public class SlotFinder implements UGraphic {
final double y = translate.getDy();
if (shape instanceof URectangle) {
final URectangle rect = (URectangle) shape;
if (rect.isIgnoreForCompression()) {
if (mode == CompressionMode.ON_X && rect.isIgnoreForCompression()) {
drawRectangle(x, y, new URectangle(2, rect.getHeight()));
drawRectangle(x + rect.getWidth() - 2, y, new URectangle(2, rect.getHeight()));
return;
}
if (mode == CompressionMode.ON_Y && rect.isIgnoreForCompression()) {
drawRectangle(x, y, new URectangle(rect.getWidth(), 2));
drawRectangle(x, y + rect.getHeight() - 2, new URectangle(rect.getWidth(), 2));
return;
}
drawRectangle(x, y, rect);
drawRectangle(x, y, (URectangle) shape);
} else if (shape instanceof UPath) {
drawPath(x, y, (UPath) shape);
} else if (shape instanceof UPolygon) {
drawPolygon(x, y, (UPolygon) shape);
} else if (shape instanceof UEllipse) {
@ -109,26 +137,55 @@ public class SlotFinder implements UGraphic {
}
}
private void drawPath(double x, double y, UPath shape) {
if (mode == CompressionMode.ON_X) {
slot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
} else {
slot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
}
}
private void drawEmpty(double x, double y, UEmpty shape) {
yslot.addSlot(y, y + shape.getHeight());
if (mode == CompressionMode.ON_X) {
slot.addSlot(x, x + shape.getWidth());
} else {
slot.addSlot(y, y + shape.getHeight());
}
}
private void drawText(double x, double y, UText shape) {
final TextLimitFinder finder = new TextLimitFinder(stringBounder, false);
finder.apply(new UTranslate(x, y)).draw(shape);
yslot.addSlot(finder.getMinY(), finder.getMaxY());
if (mode == CompressionMode.ON_X) {
slot.addSlot(finder.getMinX(), finder.getMaxX());
} else {
slot.addSlot(finder.getMinY(), finder.getMaxY());
}
}
private void drawEllipse(double x, double y, UEllipse shape) {
yslot.addSlot(y, y + shape.getHeight());
if (mode == CompressionMode.ON_X) {
slot.addSlot(x, x + shape.getWidth());
} else {
slot.addSlot(y, y + shape.getHeight());
}
}
private void drawPolygon(double x, double y, UPolygon shape) {
yslot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
if (mode == CompressionMode.ON_X) {
slot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
} else {
slot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
}
}
private void drawRectangle(double x, double y, URectangle shape) {
yslot.addSlot(y, y + shape.getHeight());
if (mode == CompressionMode.ON_X) {
slot.addSlot(x, x + shape.getWidth());
} else {
slot.addSlot(y, y + shape.getHeight());
}
}
public ColorMapper getColorMapper() {
@ -141,8 +198,8 @@ public class SlotFinder implements UGraphic {
public void closeAction() {
}
public SlotSet getYSlotSet() {
return yslot;
public SlotSet getSlotSet() {
return slot;
}
public void flushUg() {

View File

@ -33,13 +33,17 @@
*
*
*/
package net.sourceforge.plantuml.ugraphic;
package net.sourceforge.plantuml.ugraphic.comp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class SlotSet implements Iterable<Slot> {
private final List<Slot> all = new ArrayList<Slot>();

View File

@ -33,30 +33,32 @@
*
*
*/
package net.sourceforge.plantuml.graphic;
package net.sourceforge.plantuml.ugraphic.comp;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ugraphic.CompressionTransform;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.SlotFinder;
import net.sourceforge.plantuml.ugraphic.SlotSet;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicCompress;
public class TextBlockCompressed extends AbstractTextBlock implements TextBlock {
public class TextBlockCompressedOnXorY extends AbstractTextBlock implements TextBlock {
private final TextBlock textBlock;
private final CompressionMode mode;
public TextBlockCompressed(TextBlock textBlock) {
public TextBlockCompressedOnXorY(CompressionMode mode, TextBlock textBlock) {
this.textBlock = textBlock;
this.mode = mode;
}
public void drawU(final UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
final CompressionTransform compressionTransform = getCompressionTransform(stringBounder);
textBlock.drawU(new UGraphicCompress(ug, compressionTransform));
textBlock.drawU(new UGraphicCompressOnXorY(mode, ug, compressionTransform));
}
private MinMax cachedMinMax;
@ -79,9 +81,9 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
}
private CompressionTransform getCompressionTransformSlow(final StringBounder stringBounder) {
final SlotFinder slotFinder = new SlotFinder(stringBounder);
final SlotFinder slotFinder = new SlotFinder(mode, stringBounder);
textBlock.drawU(slotFinder);
final SlotSet ysSlotSet = slotFinder.getYSlotSet().reverse().smaller(5.0);
final SlotSet ysSlotSet = slotFinder.getSlotSet().reverse().smaller(5.0);
final CompressionTransform compressionTransform = new CompressionTransform(ysSlotSet);
return compressionTransform;
}
@ -89,6 +91,10 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
public Dimension2D calculateDimension(StringBounder stringBounder) {
final CompressionTransform compressionTransform = getCompressionTransform(stringBounder);
final Dimension2D dim = textBlock.calculateDimension(stringBounder);
return new Dimension2DDouble(dim.getWidth(), compressionTransform.transform(dim.getHeight()));
if (mode == CompressionMode.ON_X) {
return new Dimension2DDouble(compressionTransform.transform(dim.getWidth()), dim.getHeight());
} else {
return new Dimension2DDouble(dim.getWidth(), compressionTransform.transform(dim.getHeight()));
}
}
}

View File

@ -33,30 +33,42 @@
*
*
*/
package net.sourceforge.plantuml.ugraphic;
package net.sourceforge.plantuml.ugraphic.comp;
import net.sourceforge.plantuml.graphic.UGraphicDelegator;
import net.sourceforge.plantuml.ugraphic.UChange;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UChangeColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class UGraphicCompress extends UGraphicDelegator {
public class UGraphicCompressOnXorY extends UGraphicDelegator {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
return new UGraphicCompress(getUg(), compressionTransform, translate.compose((UTranslate) change));
return new UGraphicCompressOnXorY(mode, getUg(), compressionTransform, translate.compose((UTranslate) change));
} else if (change instanceof UStroke || change instanceof UChangeBackColor || change instanceof UChangeColor) {
return new UGraphicCompress(getUg().apply(change), compressionTransform, translate);
return new UGraphicCompressOnXorY(mode, getUg().apply(change), compressionTransform, translate);
}
throw new UnsupportedOperationException();
}
private final CompressionMode mode;
private final CompressionTransform compressionTransform;
private final UTranslate translate;
public UGraphicCompress(UGraphic ug, CompressionTransform compressionTransform) {
this(ug, compressionTransform, new UTranslate());
public UGraphicCompressOnXorY(CompressionMode mode, UGraphic ug, CompressionTransform compressionTransform) {
this(mode, ug, compressionTransform, new UTranslate());
}
private UGraphicCompress(UGraphic ug, CompressionTransform compressionTransform, UTranslate translate) {
private UGraphicCompressOnXorY(CompressionMode mode, UGraphic ug, CompressionTransform compressionTransform,
UTranslate translate) {
super(ug);
this.mode = mode;
this.compressionTransform = compressionTransform;
this.translate = translate;
}
@ -67,19 +79,32 @@ public class UGraphicCompress extends UGraphicDelegator {
if (shape instanceof URectangle) {
final URectangle rect = (URectangle) shape;
if (rect.isIgnoreForCompression()) {
final double y2 = ct(y + rect.getHeight());
shape = rect.withWidth(y2 - ct(y));
if (mode == CompressionMode.ON_X) {
final double x2 = ct(x + rect.getWidth());
shape = rect.withWidth(x2 - ct(x));
} else {
final double y2 = ct(y + rect.getHeight());
shape = rect.withHeight(y2 - ct(y));
}
}
}
if (shape instanceof ULine) {
drawLine(x, y, (ULine) shape);
} else {
getUg().apply(new UTranslate(x, ct(y))).draw(shape);
if (mode == CompressionMode.ON_X) {
getUg().apply(new UTranslate(ct(x), y)).draw(shape);
} else {
getUg().apply(new UTranslate(x, ct(y))).draw(shape);
}
}
}
private void drawLine(double x, double y, ULine shape) {
drawLine(x, ct(y), x + shape.getDX(), ct(y + shape.getDY()));
if (mode == CompressionMode.ON_X) {
drawLine(ct(x), y, ct(x + shape.getDX()), y + shape.getDY());
} else {
drawLine(x, ct(y), x + shape.getDX(), ct(y + shape.getDY()));
}
}
private double ct(double v) {
@ -92,15 +117,7 @@ public class UGraphicCompress extends UGraphicDelegator {
return;
}
assert y1 <= y2;
final double xmin = Math.min(x1, x2);
final double xmax = Math.max(x1, x2);
final double ymin = Math.min(y1, y2);
final double ymax = Math.max(y1, y2);
if (x2 >= x1) {
getUg().apply(new UTranslate(xmin, ymin)).draw(new ULine(xmax - xmin, ymax - ymin));
} else {
getUg().apply(new UTranslate(xmax, ymin)).draw(new ULine(-(xmax - xmin), ymax - ymin));
}
getUg().apply(new UTranslate(x1, y1)).draw(new ULine(x2 - x1, y2 - y1));
}
}

View File

@ -84,7 +84,6 @@ public class UGraphicTxt extends AbstractCommonUGraphic implements ClipContainer
if (shape instanceof UText) {
final UText txt = (UText) shape;
final int y = ((int) (getTranslateY() + txt.getDescent())) / 10;
System.err.println("x=" + getDx());
if (txt.getFontConfiguration().containsStyle(FontStyle.WAVE)) {
charArea.drawHLine('^', y, getDx(), txt.getText().length());
charArea.drawStringLR(txt.getText(), getDx(), y + 1);

View File

@ -0,0 +1,98 @@
/* ========================================================================
* 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.utils;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Cypher {
final private static Pattern p = Pattern.compile("[\\p{L}\\p{N}]+");
private final SecureRandom rnd = new SecureRandom();
private final Map<String, String> convert = new HashMap<String, String>();
private final Set<String> except = new HashSet<String>();
public synchronized String cypher(String s) {
final Matcher m = p.matcher(s);
final StringBuffer sb = new StringBuffer();
while (m.find()) {
final String word = m.group(0);
m.appendReplacement(sb, changeWord(word));
}
m.appendTail(sb);
return sb.toString();
}
private String changeWord(final String word) {
final String lower = word.toLowerCase();
if (except.contains(lower) || lower.matches("^[a-f0-9]{6}$")) {
return word;
}
String res = convert.get(word);
if (res != null) {
return res;
}
int len = word.length();
if (len < 4) {
len = 4;
}
while (true) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
final char letter = (char) ('a' + rnd.nextInt(26));
sb.append(letter);
}
res = sb.toString();
if (convert.containsValue(res) == false) {
convert.put(word, res);
return res;
}
}
}
public void addException(String word) {
except.add(word.toLowerCase());
}
}

View File

@ -34,6 +34,7 @@
*/
package net.sourceforge.plantuml.version;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -48,81 +49,81 @@ public enum License {
return GPL;
}
private void addMit(final List<String> text) {
private void addMit(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the MIT License.");
text.add("");
text.add(" ");
text.add("See http://opensource.org/licenses/MIT");
text.add("");
text.add(" ");
text.add("Permission is hereby granted, free of charge, to any person obtaining");
text.add("a copy of this software and associated documentation files (the \"Software\"),");
text.add("to deal in the Software without restriction, including without limitation");
text.add("the rights to use, copy, modify, merge, publish, distribute, sublicense,");
text.add("and/or sell copies of the Software, and to permit persons to whom the");
text.add("Software is furnished to do so, subject to the following conditions:");
text.add("");
text.add(" ");
text.add("The above copyright notice and this permission notice shall be included");
text.add("in all copies or substantial portions of the Software.");
text.add("");
text.add(" ");
text.add("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS");
text.add("OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,");
text.add("FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE");
text.add("AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,");
text.add("WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR");
text.add("IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the MIT License.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the MIT License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the MIT), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addEpl(final List<String> text) {
private void addEpl(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Eclipse Public License.");
text.add("");
text.add(" ");
text.add("THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC");
text.add("LICENSE (\"AGREEMENT\"). [Eclipse Public License - v 1.0]");
text.add("");
text.add(" ");
text.add("ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES");
text.add("RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.");
text.add("");
text.add(" ");
text.add("You may obtain a copy of the License at");
text.add("");
text.add(" ");
text.add("http://www.eclipse.org/legal/epl-v10.html");
text.add("");
text.add(" ");
text.add("Unless required by applicable law or agreed to in writing, software");
text.add("distributed under the License is distributed on an \"AS IS\" BASIS,");
text.add("WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
text.add("See the License for the specific language governing permissions and");
text.add("limitations under the License.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the Eclipse Public License.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the Eclipse Public License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the EPL), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addBsd(final List<String> text) {
private void addBsd(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Revised BSD License.");
text.add("");
text.add(" ");
text.add("All rights reserved.");
text.add("Redistribution and use in source and binary forms, with or without");
text.add("modification, are permitted provided that the following conditions are met:");
text.add("");
text.add(" ");
text.add("* Redistributions of source code must retain the above copyright");
text.add(" notice, this list of conditions and the following disclaimer.");
text.add("* Redistributions in binary form must reproduce the above copyright");
@ -131,7 +132,7 @@ public enum License {
text.add("* Neither the name of the University of California, Berkeley nor the");
text.add(" names of its contributors may be used to endorse or promote products");
text.add(" derived from this software without specific prior written permission.");
text.add("");
text.add(" ");
text.add("THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY");
text.add("EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED");
text.add("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE");
@ -142,159 +143,180 @@ public enum License {
text.add("ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT");
text.add("(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS");
text.add("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the Eclipse Public License.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the Eclipse Public License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the BSD), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addApache(final List<String> text) {
private void addApache(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Apache Software License.");
text.add("");
text.add(" ");
text.add("Licensed under the Apache License, Version 2.0 (the \"License\");");
text.add("you may not use this file except in compliance with the License.");
text.add("You may obtain a copy of the License at");
text.add("");
text.add(" ");
text.add("http://www.apache.org/licenses/LICENSE-2.0");
text.add("");
text.add(" ");
text.add("Unless required by applicable law or agreed to in writing, software");
text.add("distributed under the License is distributed on an \"AS IS\" BASIS,");
text.add("WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
text.add("See the License for the specific language governing permissions and");
text.add("limitations under the License.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the Apache license.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the Apache license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the Apache), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addGpl(final List<String> text) {
private void addGpl(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU General Public License as published by");
text.add("the Free Software Foundation, either version 3 of the License, or");
text.add("(at your option) any later version.");
text.add("");
text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
text.add("License for more details.");
text.add("");
text.add(" ");
text.add("You should have received a copy of the GNU General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the GPL license.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the GPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the GPL), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addGplV2(final List<String> text) {
private void addGplV2(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU General Public License as published by");
text.add("the Free Software Foundation, either version 2 of the License, or");
text.add("(at your option) any later version.");
text.add("");
text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
text.add("License for more details.");
text.add("");
text.add(" ");
text.add("You should have received a copy of the GNU General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the GPL license.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the GPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the GPL), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addLgpl(final List<String> text) {
private void addLgpl(final LicenseInfo licenseInfo, final List<String> text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU Lesser General Public License as published by");
text.add("the Free Software Foundation, either version 3 of the License, or");
text.add("(at your option) any later version.");
text.add("");
text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public");
text.add("License for more details.");
text.add("");
text.add(" ");
text.add("You should have received a copy of the GNU Lesser General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
text.add("");
addSupplementary(text);
text.add(" ");
addSupplementary(licenseInfo, text);
text.add("the LGPL license.");
text.add("");
text.add(" ");
text.add("The generated images can then be used without any reference to the LGPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("although this will be appreciate by PlantUML team.");
text.add("");
text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the LGPL), then the generated images are logically covered");
text.add("by the very same license.");
}
private void addSupplementary(final List<String> text) {
text.add("PlantUML can occasionally display sponsored or advertising messages. Those");
text.add("messages are usually generated on welcome or error images and never on");
text.add("functional diagrams.");
text.add(" ");
private void addSupplementary(final LicenseInfo licenseInfo, final List<String> text) {
if (licenseInfo.isValid() == false) {
text.add("PlantUML can occasionally display sponsored or advertising messages. Those");
text.add("messages are usually generated on welcome or error images and never on");
text.add("functional diagrams.");
text.add(" ");
}
text.add("Images (whatever their format : PNG, SVG, EPS...) generated by running PlantUML");
text.add("are owned by the author of their corresponding sources code (that is, their");
text.add("textual description in PlantUML language). Those images are not covered by");
}
private List<String> getHeaderStart() {
private List<String> getHeaderStart(LicenseInfo licenseInfo) {
final List<String> text = new ArrayList<String>();
text.add("========================================================================");
text.add("PlantUML : a free UML diagram generator");
text.add("========================================================================");
text.add("");
if (licenseInfo.isNone()) {
text.add("========================================================================");
text.add("PlantUML : a free UML diagram generator");
text.add("========================================================================");
text.add(" ");
} else {
text.add("========================================================================");
text.add("This is PlantUML Professional Edition");
text.add("========================================================================");
addLicenseInfo(text, licenseInfo);
text.add("========================================================================");
text.add(" ");
}
text.add("(C) Copyright 2009-2017, Arnaud Roques");
text.add("");
text.add(" ");
text.add("Project Info: http://plantuml.com");
text.add("");
text.add("If you like this project or if you find it useful, you can support us at:");
text.add("");
text.add("http://plantuml.com/patreon (only 1$ per month!)");
text.add("http://plantuml.com/paypal");
text.add("");
text.add(" ");
if (licenseInfo.isValid() == false) {
text.add("If you like this project or if you find it useful, you can support us at:");
text.add(" ");
text.add("http://plantuml.com/patreon (only 1$ per month!)");
text.add("http://plantuml.com/paypal");
text.add(" ");
}
return text;
}
public static void addLicenseInfo(final List<String> text, LicenseInfo licenseInfo) {
text.add("LICENSED TO : " + licenseInfo.getOwner());
text.add("EXPIRATION DATE : " + DateFormat.getDateInstance().format(licenseInfo.getExpirationDate()));
if (licenseInfo.hasExpired()) {
text.add("<i>Warning: Your license has expired.");
}
}
public List<String> getJavaHeader() {
final List<String> h = new ArrayList<String>();
h.add("/* ========================================================================");
@ -430,30 +452,31 @@ public enum License {
}
public List<String> getText() {
final List<String> text = getHeaderStart();
final LicenseInfo licenseInfo = LicenseInfo.retrieveSlow();
final List<String> text = getHeaderStart(licenseInfo);
if (this == License.GPL) {
addGpl(text);
addGpl(licenseInfo, text);
} else if (this == License.GPLV2) {
addGplV2(text);
addGplV2(licenseInfo, text);
} else if (this == License.MIT) {
addMit(text);
addMit(licenseInfo, text);
} else if (this == License.EPL) {
addEpl(text);
addEpl(licenseInfo, text);
} else if (this == License.BSD) {
addBsd(text);
addBsd(licenseInfo, text);
} else if (this == License.APACHE) {
addApache(text);
addApache(licenseInfo, text);
} else if (this == License.LGPL) {
addLgpl(text);
addLgpl(licenseInfo, text);
} else {
throw new IllegalStateException();
}
if (OptionFlags.getInstance().isEnableStats()) {
text.add("");
text.add(" ");
text.add("This version of PlantUML records general local statistics about usage.");
text.add("(more info on http://plantuml.com/statistics-report)");
}
text.add("");
text.add(" ");
text.add("Icons provided by OpenIconic : https://useiconic.com/open");
text.add("Archimate sprites provided by Archi : http://www.archimatetool.com");
text.add("Stdlib AWS provided by https://github.com/milo-minderbinder/AWS-PlantUML");
@ -462,8 +485,7 @@ public enum License {
text.add("ASCIIMathML (c) David Lippman http://www.pierce.ctc.edu/dlippman");
text.add("CafeUndZopfli ported by Eugene Klyuchnikov https://github.com/eustas/CafeUndZopfli");
text.add("Brotli (c) by the Brotli Authors https://github.com/google/brotli");
text.add("");
text.add(" ");
return text;
}
}

View File

@ -0,0 +1,221 @@
/* ========================================================================
* 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.version;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.SignatureUtils;
import net.sourceforge.plantuml.dedication.Dedication;
import net.sourceforge.plantuml.dedication.QBlock;
public class LicenseInfo {
private final static Preferences prefs = Preferences.userNodeForPackage(LicenseInfo.class);
private final static LicenseInfo NONE = new LicenseInfo();
public static final int POS_TYPE = 2;
public static final int POS_SIGNATURE = 10;
public static final int POS_GENERATION = 100;
public static final int POS_EXPIRATION = 108;
public static final int POS_OWNER = 128;
private final long generationDate;
private final long expirationDate;
private final String owner;
private LicenseInfo() {
this.expirationDate = 0;
this.generationDate = 0;
this.owner = null;
}
private LicenseInfo(Magic magic) throws NoSuchAlgorithmException, IOException {
final String signature = SignatureUtils.toHexString(magic.get(LicenseInfo.POS_SIGNATURE, 64));
final String local = SignatureUtils.toHexString(Magic.signature());
if (local.equals(signature) == false) {
throw new IOException();
}
final int type = magic.getByte(Magic.signature(), LicenseInfo.POS_TYPE);
this.generationDate = bytesToLong(magic.get(LicenseInfo.POS_GENERATION, 8));
this.expirationDate = bytesToLong(magic.get(LicenseInfo.POS_EXPIRATION, 8));
this.owner = magic.getString(LicenseInfo.POS_OWNER);
}
public static long bytesToLong(byte[] b) {
long result = 0;
for (int i = 0; i < 8; i++) {
result <<= 8;
result |= (b[i] & 0xFF);
}
return result;
}
public static void persistMe(String key) throws BackingStoreException {
prefs.sync();
prefs.put("license", key);
}
private static LicenseInfo cache;
public static synchronized LicenseInfo retrieveQuick() {
if (cache == null) {
return retrieveSlow();
}
return cache;
}
public static synchronized LicenseInfo retrieveSlow() {
cache = LicenseInfo.NONE;
final String key = prefs.get("license", "");
if (key.length() > 0) {
cache = setIfValid(retrieve(key), cache);
if (cache.isValid()) {
return cache;
}
}
for (File f : fileCandidates()) {
try {
if (f.exists() && f.canRead()) {
final LicenseInfo result = retrieve(f);
cache = setIfValid(result, cache);
if (cache.isValid()) {
return cache;
}
}
} catch (IOException e) {
Log.info("Error " + e);
// e.printStackTrace();
}
}
return cache;
}
private static LicenseInfo setIfValid(LicenseInfo value, LicenseInfo def) {
if (value.isValid() || def.isNone()) {
return value;
}
return def;
}
private static LicenseInfo retrieve(File f) throws IOException {
final BufferedReader br = new BufferedReader(new FileReader(f));
final String s = br.readLine();
br.close();
final LicenseInfo result = retrieve(s);
if (result != null) {
Log.info("Reading license from " + f.getAbsolutePath());
}
return result;
}
public static LicenseInfo retrieve(final String key) {
if (key.matches("^[0-9a-z]+$")) {
try {
final BigInteger lu = new BigInteger(key, 36);
final QBlock qb2 = new QBlock(lu);
final QBlock qb3 = qb2.change(Dedication.E, Dedication.N);
final Magic magic = qb3.toMagic();
final String sig = SignatureUtils.toHexString(Magic.signature());
magic.xor(SignatureUtils.getSHA512raw(SignatureUtils.salting(sig, Magic.getSalt(sig))));
return new LicenseInfo(magic);
} catch (Exception e) {
// e.printStackTrace();
Log.info("Error " + e);
}
}
return LicenseInfo.NONE;
}
public static Collection<File> fileCandidates() {
final Set<File> result = new TreeSet<File>();
final String classpath = System.getProperty("java.class.path");
String[] classpathEntries = classpath.split(File.pathSeparator);
for (String s : classpathEntries) {
File dir = new File(s);
if (dir.isFile()) {
dir = dir.getParentFile();
}
if (dir.isDirectory()) {
result.add(new File(dir, "license.txt"));
}
}
return result;
}
public static void main(String[] args) {
LicenseInfo info = retrieveSlow();
System.err.println("valid=" + info.isValid());
System.err.println("info=" + info.owner);
}
public final Date getGenerationDate() {
return new Date(generationDate);
}
public final Date getExpirationDate() {
return new Date(expirationDate);
}
public final String getOwner() {
return owner;
}
public boolean isNone() {
return owner == null;
}
public boolean isValid() {
return owner != null && System.currentTimeMillis() <= this.expirationDate;
}
public boolean hasExpired() {
return owner != null && System.currentTimeMillis() > this.expirationDate;
}
}

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