1
0
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:
Arnaud Roques 2022-11-19 15:57:30 +01:00
parent 665cae15ba
commit 6e25b30d60
19 changed files with 289 additions and 110 deletions

View File

@ -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;
}

View 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);
}
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}

View File

@ -184,9 +184,9 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
@Override
public String getPatternEnd() {
if (withBracket) {
if (withBracket)
return "^(\\})$";
}
return "^[%s]*(end[%s]?note)$";
}

View File

@ -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();
}

View File

@ -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,

View File

@ -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() {

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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() {

View File

@ -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() {