mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 10:59:01 +00:00
Improve compression management
This commit is contained in:
parent
665cae15ba
commit
6e25b30d60
@ -44,7 +44,7 @@ public class LineBreakStrategy {
|
||||
public LineBreakStrategy(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
@ -55,9 +55,9 @@ public class LineBreakStrategy {
|
||||
}
|
||||
|
||||
public double getMaxWidth() {
|
||||
if (value != null && value.matches("-?\\d+")) {
|
||||
if (value != null && value.matches("-?\\d+"))
|
||||
return Double.parseDouble(value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
73
src/net/sourceforge/plantuml/code/CompressionZip.java
Normal file
73
src/net/sourceforge/plantuml/code/CompressionZip.java
Normal file
@ -0,0 +1,73 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2023, 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.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class CompressionZip implements Compression {
|
||||
|
||||
public byte[] compress(byte[] in) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public ByteArray decompress(byte[] input) throws NoPlantumlCompressionException {
|
||||
try {
|
||||
try (final ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(input))) {
|
||||
final ZipEntry ent = zis.getNextEntry();
|
||||
final String name = ent.getName();
|
||||
final byte[] buffer = new byte[10_000];
|
||||
|
||||
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
baos.write(buffer, 0, len);
|
||||
if (baos.size() > 200_000)
|
||||
throw new NoPlantumlCompressionException("Zip error");
|
||||
}
|
||||
return ByteArray.from(baos.toByteArray());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new NoPlantumlCompressionException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -47,16 +47,16 @@ public class CompressionZlib implements Compression {
|
||||
private static final int COMPRESSION_LEVEL = 9;
|
||||
|
||||
public byte[] compress(byte[] in) {
|
||||
if (USE_ZOPFLI) {
|
||||
if (USE_ZOPFLI)
|
||||
return new CompressionZopfliZlib().compress(in);
|
||||
}
|
||||
if (in.length == 0) {
|
||||
|
||||
if (in.length == 0)
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = in.length * 2;
|
||||
if (len < 1000) {
|
||||
if (len < 1000)
|
||||
len = 1000;
|
||||
}
|
||||
|
||||
// Compress the bytes
|
||||
final Deflater compresser = new Deflater(COMPRESSION_LEVEL, true);
|
||||
compresser.setInput(in);
|
||||
@ -64,9 +64,9 @@ public class CompressionZlib implements Compression {
|
||||
|
||||
final byte[] output = new byte[len];
|
||||
final int compressedDataLength = compresser.deflate(output);
|
||||
if (compresser.finished() == false) {
|
||||
if (compresser.finished() == false)
|
||||
return null;
|
||||
}
|
||||
|
||||
return copyArray(output, compressedDataLength);
|
||||
}
|
||||
|
||||
|
@ -47,16 +47,16 @@ public class CompressionZlibAttic implements Compression {
|
||||
private static final int COMPRESSION_LEVEL = 9;
|
||||
|
||||
public byte[] compress(byte[] in) {
|
||||
if (USE_ZOPFLI) {
|
||||
if (USE_ZOPFLI)
|
||||
return new CompressionZopfliZlib().compress(in);
|
||||
}
|
||||
if (in.length == 0) {
|
||||
|
||||
if (in.length == 0)
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = in.length * 2;
|
||||
if (len < 1000) {
|
||||
if (len < 1000)
|
||||
len = 1000;
|
||||
}
|
||||
|
||||
byte[] result = null;
|
||||
result = tryCompress(in, len);
|
||||
return result;
|
||||
@ -70,9 +70,9 @@ public class CompressionZlibAttic implements Compression {
|
||||
|
||||
final byte[] output = new byte[len];
|
||||
final int compressedDataLength = compresser.deflate(output);
|
||||
if (compresser.finished() == false) {
|
||||
if (compresser.finished() == false)
|
||||
return null;
|
||||
}
|
||||
|
||||
return copyArray(output, compressedDataLength);
|
||||
}
|
||||
|
||||
@ -84,11 +84,9 @@ public class CompressionZlibAttic implements Compression {
|
||||
int len = 100_000;
|
||||
byte[] result = null;
|
||||
result = tryDecompress(in2, len);
|
||||
if (result == null) {
|
||||
if (result == null)
|
||||
throw new NoPlantumlCompressionException("Too big?");
|
||||
|
||||
}
|
||||
|
||||
return ByteArray.from(result);
|
||||
} catch (IOException e) {
|
||||
// Logme.error(e);
|
||||
@ -98,18 +96,18 @@ public class CompressionZlibAttic implements Compression {
|
||||
}
|
||||
|
||||
private byte[] tryDecompress(byte[] in, final int len) throws IOException {
|
||||
if (len > 200_000) {
|
||||
if (len > 200_000)
|
||||
throw new IOException("OutOfMemory");
|
||||
}
|
||||
|
||||
// Decompress the bytes
|
||||
final byte[] tmp = new byte[len];
|
||||
final Inflater decompresser = new Inflater(true);
|
||||
decompresser.setInput(in);
|
||||
try {
|
||||
final int resultLength = decompresser.inflate(tmp);
|
||||
if (decompresser.finished() == false) {
|
||||
if (decompresser.finished() == false)
|
||||
return null;
|
||||
}
|
||||
|
||||
decompresser.end();
|
||||
|
||||
final byte[] result = copyArray(tmp, resultLength);
|
||||
|
@ -43,13 +43,13 @@ import net.sourceforge.plantuml.zopfli.Zopfli;
|
||||
public class CompressionZopfliZlib implements Compression {
|
||||
|
||||
public byte[] compress(byte[] in) {
|
||||
if (in.length == 0) {
|
||||
if (in.length == 0)
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = in.length * 2;
|
||||
if (len < 100) {
|
||||
if (len < 100)
|
||||
len = 100;
|
||||
}
|
||||
|
||||
final Zopfli compressor = new Zopfli(len);
|
||||
final Options options = new Options(OutputFormat.DEFLATE, BlockSplitting.FIRST, 30);
|
||||
|
||||
|
@ -46,20 +46,24 @@ public class TranscoderSmart implements Transcoder {
|
||||
new CompressionZlib());
|
||||
private final Transcoder hexOnly = TranscoderImpl.utf8(new AsciiEncoderHex(), new ArobaseStringCompressor(),
|
||||
new CompressionNone());
|
||||
private final Transcoder zip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
|
||||
new CompressionZip());
|
||||
|
||||
public String decode(String code) throws NoPlantumlCompressionException {
|
||||
// Work in progress
|
||||
// See https://github.com/plantuml/plantuml/issues/117
|
||||
|
||||
if (code.startsWith("~0")) {
|
||||
if (code.startsWith("~0"))
|
||||
return zlib.decode(code.substring(2));
|
||||
}
|
||||
if (code.startsWith("~1")) {
|
||||
|
||||
if (code.startsWith("~1"))
|
||||
return oldOne.decode(code.substring(2));
|
||||
}
|
||||
if (code.startsWith("~h")) {
|
||||
|
||||
if (code.startsWith("~h"))
|
||||
return hexOnly.decode(code.substring(2));
|
||||
}
|
||||
|
||||
if (code.startsWith("~zip~"))
|
||||
return zip.decode(code.substring(5));
|
||||
|
||||
try {
|
||||
return zlib.decode(code);
|
||||
|
@ -46,20 +46,24 @@ public class TranscoderSmartProtected implements Transcoder {
|
||||
new CompressionZlib());
|
||||
private final Transcoder hexOnly = TranscoderImpl.utf8(new AsciiEncoderHex(), new ArobaseStringCompressor(),
|
||||
new CompressionNone());
|
||||
private final Transcoder zip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
|
||||
new CompressionZip());
|
||||
|
||||
public String decode(String code) throws NoPlantumlCompressionException {
|
||||
// Work in progress
|
||||
// See https://github.com/plantuml/plantuml/issues/117
|
||||
|
||||
if (code.startsWith("~0")) {
|
||||
if (code.startsWith("~0"))
|
||||
return decodeZlib(code.substring(2));
|
||||
}
|
||||
if (code.startsWith("~1")) {
|
||||
|
||||
if (code.startsWith("~1"))
|
||||
return decodeHuffman(code.substring(2));
|
||||
}
|
||||
if (code.startsWith("~h")) {
|
||||
|
||||
if (code.startsWith("~h"))
|
||||
return hexOnly.decode(code.substring(2));
|
||||
}
|
||||
|
||||
if (code.startsWith("~zip~"))
|
||||
return zip.decode(code.substring(5));
|
||||
|
||||
return decodeZlib(code);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.command.note;
|
||||
|
||||
import net.sourceforge.plantuml.ColorParam;
|
||||
import net.sourceforge.plantuml.LineLocation;
|
||||
import net.sourceforge.plantuml.baraye.IEntity;
|
||||
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
|
||||
@ -54,6 +55,7 @@ import net.sourceforge.plantuml.cucadiagram.Code;
|
||||
import net.sourceforge.plantuml.cucadiagram.Ident;
|
||||
import net.sourceforge.plantuml.cucadiagram.LeafType;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotag;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotype;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorParser;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorType;
|
||||
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
|
||||
@ -70,6 +72,8 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand<Abstr
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
ColorParser.exp1(), //
|
||||
RegexLeaf.end() //
|
||||
);
|
||||
@ -89,6 +93,8 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand<Abstr
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
ColorParser.exp1(), //
|
||||
RegexLeaf.end() //
|
||||
);
|
||||
@ -134,14 +140,21 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand<Abstr
|
||||
final Ident ident = diagram.buildLeafIdent(idShort);
|
||||
final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort);
|
||||
final boolean leafExist = diagram.V1972() ? diagram.leafExistSmart(ident) : diagram.leafExist(code);
|
||||
if (leafExist) {
|
||||
if (leafExist)
|
||||
return CommandExecutionResult.error("Note already created: " + code.getName());
|
||||
}
|
||||
|
||||
final IEntity entity = diagram.createLeaf(ident, code, display.toDisplay(), LeafType.NOTE, null);
|
||||
assert entity != null;
|
||||
final String s = arg.get("COLOR", 0);
|
||||
entity.setSpecificColorTOBEREMOVED(ColorType.BACK, s == null ? null
|
||||
: diagram.getSkinParam().getIHtmlColorSet().getColor(s));
|
||||
entity.setSpecificColorTOBEREMOVED(ColorType.BACK,
|
||||
s == null ? null : diagram.getSkinParam().getIHtmlColorSet().getColor(s));
|
||||
final String stereotypeString = arg.get("STEREO", 0);
|
||||
Stereotype stereotype = null;
|
||||
if (stereotypeString != null) {
|
||||
stereotype = Stereotype.build(stereotypeString);
|
||||
entity.setStereotype(stereotype);
|
||||
}
|
||||
|
||||
CommandCreateClassMultilines.addTags(entity, arg.get("TAGS", 0));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
@ -184,9 +184,9 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
|
||||
|
||||
@Override
|
||||
public String getPatternEnd() {
|
||||
if (withBracket) {
|
||||
if (withBracket)
|
||||
return "^(\\})$";
|
||||
}
|
||||
|
||||
return "^[%s]*(end[%s]?note)$";
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.command.note;
|
||||
|
||||
import net.sourceforge.plantuml.ColorParam;
|
||||
import net.sourceforge.plantuml.StringUtils;
|
||||
import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.UrlBuilder;
|
||||
@ -59,7 +60,11 @@ import net.sourceforge.plantuml.cucadiagram.Link;
|
||||
import net.sourceforge.plantuml.cucadiagram.LinkArg;
|
||||
import net.sourceforge.plantuml.cucadiagram.LinkDecor;
|
||||
import net.sourceforge.plantuml.cucadiagram.LinkType;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotag;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotype;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorParser;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorType;
|
||||
import net.sourceforge.plantuml.graphic.color.Colors;
|
||||
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
|
||||
|
||||
public final class CommandFactoryTipOnEntity implements SingleMultiFactoryCommand<AbstractEntityDiagram> {
|
||||
@ -83,6 +88,12 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
partialPattern, //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
ColorParser.exp1(), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
@ -100,6 +111,12 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
partialPattern, //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
ColorParser.exp1(), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
@ -107,6 +124,10 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
|
||||
);
|
||||
}
|
||||
|
||||
private static ColorParser color() {
|
||||
return ColorParser.simpleColor(ColorType.BACK);
|
||||
}
|
||||
|
||||
public Command<AbstractEntityDiagram> createSingleLine() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@ -165,16 +186,31 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
|
||||
tips = diagram.getOrCreateLeaf(identTip, identTip.toCode(diagram), LeafType.TIPS, null);
|
||||
final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getInvisible();
|
||||
final Link link;
|
||||
if (position == Position.RIGHT) {
|
||||
if (position == Position.RIGHT)
|
||||
link = new Link(diagram.getIEntityFactory(), diagram.getSkinParam().getCurrentStyleBuilder(), cl1,
|
||||
(IEntity) tips, type, LinkArg.noDisplay(1));
|
||||
} else {
|
||||
else
|
||||
link = new Link(diagram.getIEntityFactory(), diagram.getSkinParam().getCurrentStyleBuilder(),
|
||||
(IEntity) tips, cl1, type, LinkArg.noDisplay(1));
|
||||
}
|
||||
|
||||
diagram.addLink(link);
|
||||
}
|
||||
tips.putTip(member, lines.toDisplay());
|
||||
|
||||
Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet());
|
||||
|
||||
final String stereotypeString = line0.get("STEREO", 0);
|
||||
Stereotype stereotype = null;
|
||||
if (stereotypeString != null) {
|
||||
stereotype = Stereotype.build(stereotypeString);
|
||||
colors = colors.applyStereotypeForNote(stereotype, diagram.getSkinParam(), ColorParam.noteBackground,
|
||||
ColorParam.noteBorder);
|
||||
}
|
||||
if (stereotypeString != null)
|
||||
tips.setStereotype(stereotype);
|
||||
|
||||
tips.setColors(colors);
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
new RegexLeaf("STEREO1", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("over"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
@ -83,6 +83,8 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("P2", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO2", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
color().getRegex(), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), RegexLeaf.end() //
|
||||
@ -96,7 +98,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO", "(\\<{2}.*\\>{2})?"), //
|
||||
new RegexLeaf("STEREO1", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("over"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
@ -106,6 +108,8 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("P2", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("STEREO2", "(\\<{2}.*\\>{2})?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
color().getRegex(), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
@ -166,7 +170,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
|
||||
final Display display = diagram.manageVariable(lines.toDisplay());
|
||||
final Note note = new Note(p1, p2, display, diagram.getSkinParam().getCurrentStyleBuilder());
|
||||
Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet());
|
||||
final String stereotypeString = line0.get("STEREO", 0);
|
||||
final String stereotypeString = line0.getLazzy("STEREO", 0);
|
||||
if (stereotypeString != null) {
|
||||
final Stereotype stereotype = Stereotype.build(stereotypeString);
|
||||
colors = colors.applyStereotypeForNote(stereotype, diagram.getSkinParam(), ColorParam.noteBackground,
|
||||
|
@ -37,7 +37,6 @@ package net.sourceforge.plantuml.creole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -46,7 +45,6 @@ import net.sourceforge.plantuml.LineBreakStrategy;
|
||||
import net.sourceforge.plantuml.awt.geom.XDimension2D;
|
||||
import net.sourceforge.plantuml.creole.atom.AbstractAtom;
|
||||
import net.sourceforge.plantuml.creole.atom.Atom;
|
||||
import net.sourceforge.plantuml.creole.legacy.AtomText;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
|
||||
@ -62,18 +60,18 @@ public class Fission {
|
||||
|
||||
public List<Stripe> getSplitted(StringBounder stringBounder) {
|
||||
final double valueMaxWidth = maxWidth.getMaxWidth();
|
||||
if (valueMaxWidth == 0) {
|
||||
if (valueMaxWidth == 0)
|
||||
return Arrays.asList(stripe);
|
||||
}
|
||||
|
||||
final List<Stripe> result = new ArrayList<>();
|
||||
StripeSimpleInternal current = new StripeSimpleInternal(stripe.getLHeader());
|
||||
double remainingSpace = valueMaxWidth;
|
||||
for (Atom atom : noHeader()) {
|
||||
for (Atom atom : noHeader())
|
||||
while (true) {
|
||||
final List<Atom> splitInTwo = atom.splitInTwo(stringBounder, remainingSpace);
|
||||
final Atom part1 = splitInTwo.get(0);
|
||||
final double widthPart1 = part1.calculateDimension(stringBounder).getWidth();
|
||||
current.addAtom(part1, widthPart1);
|
||||
current.addAtom(part1);
|
||||
remainingSpace -= widthPart1;
|
||||
if (remainingSpace <= 0) {
|
||||
result.add(current);
|
||||
@ -91,25 +89,25 @@ public class Fission {
|
||||
remainingSpace = valueMaxWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remainingSpace < valueMaxWidth) {
|
||||
|
||||
if (remainingSpace < valueMaxWidth)
|
||||
result.add(current);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
private List<Atom> noHeader() {
|
||||
final List<Atom> atoms = stripe.getAtoms();
|
||||
if (stripe.getLHeader() == null) {
|
||||
if (stripe.getLHeader() == null)
|
||||
return atoms;
|
||||
}
|
||||
|
||||
return atoms.subList(1, atoms.size());
|
||||
}
|
||||
|
||||
private static Atom blank(final Atom header) {
|
||||
if (header == null) {
|
||||
if (header == null)
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AbstractAtom() {
|
||||
|
||||
public XDimension2D calculateDimension(StringBounder stringBounder) {
|
||||
@ -126,31 +124,22 @@ public class Fission {
|
||||
};
|
||||
}
|
||||
|
||||
private Collection<? extends Atom> getSplitted(StringBounder stringBounder, Atom atom) {
|
||||
if (atom instanceof AtomText) {
|
||||
return ((AtomText) atom).getSplitted(stringBounder, maxWidth);
|
||||
}
|
||||
return Collections.singleton(atom);
|
||||
}
|
||||
|
||||
static class StripeSimpleInternal implements Stripe {
|
||||
|
||||
private final List<Atom> atoms = new ArrayList<>();
|
||||
private double totalWidth;
|
||||
|
||||
private StripeSimpleInternal(Atom header) {
|
||||
if (header != null) {
|
||||
if (header != null)
|
||||
this.atoms.add(header);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<Atom> getAtoms() {
|
||||
return Collections.unmodifiableList(atoms);
|
||||
}
|
||||
|
||||
private void addAtom(Atom atom, double width) {
|
||||
private void addAtom(Atom atom) {
|
||||
this.atoms.add(atom);
|
||||
this.totalWidth += width;
|
||||
}
|
||||
|
||||
public Atom getLHeader() {
|
||||
|
@ -2,8 +2,10 @@ package net.sourceforge.plantuml.preproc;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -22,8 +24,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.brotli.BrotliInputStream;
|
||||
import net.sourceforge.plantuml.code.Base64Coder;
|
||||
import net.sourceforge.plantuml.creole.atom.AtomImg;
|
||||
import net.sourceforge.plantuml.log.Logme;
|
||||
import net.sourceforge.plantuml.security.SFile;
|
||||
|
||||
@ -90,6 +96,14 @@ public class Stdlib {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int read1byte(InputStream is) throws IOException {
|
||||
return is.read() & 0xFF;
|
||||
}
|
||||
|
||||
private static int read2bytes(InputStream is) throws IOException {
|
||||
return (read1byte(is) << 8) + read1byte(is);
|
||||
}
|
||||
|
||||
private String loadResource(String file) throws IOException {
|
||||
final SoftReference<String> cached = cache.get(file.toLowerCase());
|
||||
if (cached != null) {
|
||||
@ -110,6 +124,8 @@ public class Stdlib {
|
||||
dataStream.close();
|
||||
return null;
|
||||
}
|
||||
InputStream dataImagePngBase64Stream = null;
|
||||
final List<Integer> colors = new ArrayList<>();
|
||||
try {
|
||||
StringBuilder found = null;
|
||||
while (true) {
|
||||
@ -122,7 +138,7 @@ public class Stdlib {
|
||||
found = new StringBuilder();
|
||||
|
||||
while (true) {
|
||||
final String s = dataStream.readUTF();
|
||||
String s = dataStream.readUTF();
|
||||
if (s.equals(SEPARATOR)) {
|
||||
if (found != null) {
|
||||
final String result = found.toString();
|
||||
@ -131,6 +147,24 @@ public class Stdlib {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (s.contains(AtomImg.DATA_IMAGE_PNG_BASE64)) {
|
||||
if (dataImagePngBase64Stream == null) {
|
||||
dataImagePngBase64Stream = getDataImagePngBase64();
|
||||
final int size = read2bytes(dataImagePngBase64Stream);
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int alpha = read1byte(dataImagePngBase64Stream);
|
||||
final int red = read1byte(dataImagePngBase64Stream);
|
||||
final int green = read1byte(dataImagePngBase64Stream);
|
||||
final int blue = read1byte(dataImagePngBase64Stream);
|
||||
final int rgb = (alpha << 24) + (red << 16) + (green << 8) + blue;
|
||||
colors.add(rgb);
|
||||
}
|
||||
}
|
||||
final String base64 = readOneImage(dataImagePngBase64Stream, colors);
|
||||
s = s.replaceFirst(AtomImg.DATA_IMAGE_PNG_BASE64, AtomImg.DATA_IMAGE_PNG_BASE64 + base64);
|
||||
}
|
||||
|
||||
if (found != null) {
|
||||
found.append(s);
|
||||
found.append("\n");
|
||||
@ -156,6 +190,27 @@ public class Stdlib {
|
||||
} finally {
|
||||
dataStream.close();
|
||||
spriteStream.close();
|
||||
if (dataImagePngBase64Stream != null)
|
||||
dataImagePngBase64Stream.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String readOneImage(InputStream is, List<Integer> colors) throws IOException {
|
||||
final int width = is.read();
|
||||
final int height = is.read();
|
||||
|
||||
final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
for (int y = 0; y < height; y += 1)
|
||||
for (int x = 0; x < width; x += 1) {
|
||||
final int rgb = colors.get(read2bytes(is));
|
||||
result.setRGB(x, y, rgb);
|
||||
}
|
||||
|
||||
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
ImageIO.write(result, "png", baos);
|
||||
return new String(Base64Coder.encode(baos.toByteArray()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -228,7 +283,13 @@ public class Stdlib {
|
||||
final InputStream raw = getInternalInputStream(name, "-dex.repx");
|
||||
if (raw == null)
|
||||
return null;
|
||||
return new BrotliInputStream(raw);
|
||||
}
|
||||
|
||||
private InputStream getDataImagePngBase64() throws IOException {
|
||||
final InputStream raw = getInternalInputStream(name, "-ghx.repx");
|
||||
if (raw == null)
|
||||
return null;
|
||||
return new BrotliInputStream(raw);
|
||||
}
|
||||
|
||||
|
@ -134,31 +134,30 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
|
||||
synchronized (cache) {
|
||||
if (cache.size() == 0) {
|
||||
|
||||
for (Subject subject : subjects()) {
|
||||
for (Subject subject : subjects())
|
||||
for (SentenceSimple sentenceA : subject.getSentences()) {
|
||||
cache.add(NaturalCommand.create(sentenceA));
|
||||
for (SentenceSimple sentenceB : subject.getSentences()) {
|
||||
if (sentenceA.getVerbPattern().equals(sentenceB.getVerbPattern()) == false) {
|
||||
final String signatureA = sentenceA.getSignature();
|
||||
final String signatureB = sentenceB.getSignature();
|
||||
if (signatureA.equals(signatureB) == false)
|
||||
cache.add(NaturalCommand.create(new SentenceAnd(sentenceA, sentenceB)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Subject subject : subjects()) {
|
||||
for (SentenceSimple sentenceA : subject.getSentences()) {
|
||||
for (SentenceSimple sentenceB : subject.getSentences()) {
|
||||
for (Subject subject : subjects())
|
||||
for (SentenceSimple sentenceA : subject.getSentences())
|
||||
for (SentenceSimple sentenceB : subject.getSentences())
|
||||
for (SentenceSimple sentenceC : subject.getSentences()) {
|
||||
if (sentenceA.getVerbPattern().equals(sentenceB.getVerbPattern()) == false
|
||||
&& sentenceA.getVerbPattern().equals(sentenceC.getVerbPattern()) == false
|
||||
&& sentenceC.getVerbPattern().equals(sentenceB.getVerbPattern()) == false) {
|
||||
final String signatureA = sentenceA.getSignature();
|
||||
final String signatureB = sentenceB.getSignature();
|
||||
final String signatureC = sentenceC.getSignature();
|
||||
if (signatureA.equals(signatureB) == false && signatureA.equals(signatureC) == false
|
||||
&& signatureC.equals(signatureB) == false)
|
||||
cache.add(
|
||||
NaturalCommand.create(new SentenceAndAnd(sentenceA, sentenceB, sentenceC)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
|
@ -55,6 +55,10 @@ public abstract class SentenceSimple implements Sentence {
|
||||
this.complementii = complement;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return subjectii.getClass() + "/" + verb.getPattern() + "/" + complementii.getClass();
|
||||
}
|
||||
|
||||
public final IRegex toRegex() {
|
||||
if (complementii instanceof ComplementEmpty)
|
||||
return new RegexConcat(//
|
||||
@ -89,10 +93,6 @@ public abstract class SentenceSimple implements Sentence {
|
||||
|
||||
public abstract CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement);
|
||||
|
||||
public final String getVerbPattern() {
|
||||
return verb.getPattern();
|
||||
}
|
||||
|
||||
public IRegex getVerbRegex() {
|
||||
return verb;
|
||||
}
|
||||
|
@ -36,9 +36,7 @@ public final class QColor {
|
||||
red = alpha * red;
|
||||
green = alpha * green;
|
||||
blue = alpha * blue;
|
||||
|
||||
} else {
|
||||
|
||||
red = 1 - alpha * (1 - red);
|
||||
green = 1 - alpha * (1 - green);
|
||||
blue = 1 - alpha * (1 - blue);
|
||||
|
@ -67,6 +67,7 @@ import net.sourceforge.plantuml.skin.rose.Rose;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.style.StyleSignature;
|
||||
import net.sourceforge.plantuml.style.StyleSignatureBasic;
|
||||
import net.sourceforge.plantuml.svek.AbstractEntityImage;
|
||||
import net.sourceforge.plantuml.svek.ShapeType;
|
||||
@ -88,7 +89,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
|
||||
private final int marginX1 = 6;
|
||||
private final int marginX2 = 15;
|
||||
private final int marginY = 5;
|
||||
private final boolean withShadow;
|
||||
|
||||
private final ISkinParam skinParam;
|
||||
private final Style style;
|
||||
|
||||
@ -98,7 +99,6 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
|
||||
super(entity, getSkin(getISkinParam(skinParam, entity), entity));
|
||||
this.skinParam = getISkinParam(skinParam, entity);
|
||||
|
||||
this.withShadow = getSkinParam().shadowing(getEntity().getStereotype());
|
||||
final Display strings = entity.getDisplay();
|
||||
|
||||
this.style = getDefaultStyleDefinition(umlDiagramType.getStyleName())
|
||||
@ -186,8 +186,8 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
|
||||
return new XDimension2D(width, height);
|
||||
}
|
||||
|
||||
private StyleSignatureBasic getDefaultStyleDefinition(SName sname) {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.note);
|
||||
private StyleSignature getDefaultStyleDefinition(SName sname) {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.note).withTOBECHANGED(getStereo());
|
||||
}
|
||||
|
||||
final public void drawU(UGraphic ug) {
|
||||
|
@ -58,6 +58,7 @@ import net.sourceforge.plantuml.skin.rose.Rose;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
import net.sourceforge.plantuml.style.StyleSignature;
|
||||
import net.sourceforge.plantuml.style.StyleSignatureBasic;
|
||||
import net.sourceforge.plantuml.svek.AbstractEntityImage;
|
||||
import net.sourceforge.plantuml.svek.Bibliotekon;
|
||||
@ -70,7 +71,6 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
public class EntityImageTips extends AbstractEntityImage {
|
||||
|
||||
final private Rose rose = new Rose();
|
||||
private final ISkinParam skinParam;
|
||||
|
||||
private final HColor noteBackgroundColor;
|
||||
@ -96,8 +96,8 @@ public class EntityImageTips extends AbstractEntityImage {
|
||||
|
||||
}
|
||||
|
||||
private StyleSignatureBasic getDefaultStyleDefinition(SName sname) {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.note);
|
||||
private StyleSignature getDefaultStyleDefinition(SName sname) {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.note).withTOBECHANGED(getStereo());
|
||||
}
|
||||
|
||||
private Position getPosition() {
|
||||
|
@ -45,7 +45,7 @@ public class Version {
|
||||
private static final int MAJOR_SEPARATOR = 1000000;
|
||||
|
||||
public static int version() {
|
||||
return 1202212;
|
||||
return 1202213;
|
||||
}
|
||||
|
||||
public static int versionPatched() {
|
||||
@ -81,7 +81,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static int beta() {
|
||||
final int beta = 8;
|
||||
final int beta = 0;
|
||||
return beta;
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static long compileTime() {
|
||||
return 1666548746412L;
|
||||
return 1668864137549L;
|
||||
}
|
||||
|
||||
public static String compileTimeString() {
|
||||
|
Loading…
Reference in New Issue
Block a user