1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00
This commit is contained in:
Arnaud Roques 2022-07-27 15:51:02 +02:00
parent 0fc2fad432
commit dd53272c19
18 changed files with 692 additions and 352 deletions

View File

@ -185,6 +185,12 @@ public class CommandCreateElementFull2 extends SingleLineCommand2<ClassDiagram>
} else if (symbol.equalsIgnoreCase("port")) {
type = LeafType.PORT;
usymbol = null;
} else if (symbol.equalsIgnoreCase("portin")) {
type = LeafType.PORTIN;
usymbol = null;
} else if (symbol.equalsIgnoreCase("portout")) {
type = LeafType.PORTOUT;
usymbol = null;
} else if (symbol.equalsIgnoreCase("usecase")) {
type = LeafType.USECASE;
usymbol = null;

View File

@ -68,9 +68,9 @@ public class BlocLines implements Iterable<StringLocated> {
public static BlocLines load(SFile f, LineLocation location) throws IOException {
final BufferedReader br = f.openBufferedReader();
if (br == null) {
if (br == null)
return null;
}
return loadInternal(br, location);
}
@ -87,9 +87,8 @@ public class BlocLines implements Iterable<StringLocated> {
final List<StringLocated> result = new ArrayList<>();
String s;
try {
while ((s = br.readLine()) != null) {
while ((s = br.readLine()) != null)
result.add(new StringLocated(s, location));
}
} finally {
br.close();
}
@ -118,17 +117,17 @@ public class BlocLines implements Iterable<StringLocated> {
public static BlocLines fromArray(String[] array) {
final List<StringLocated> result = new ArrayList<>();
for (String single : array) {
for (String single : array)
result.add(new StringLocated(single, null));
}
return new BlocLines(result);
}
public static BlocLines getWithNewlines(String s) {
final List<StringLocated> result = new ArrayList<>();
for (String cs : BackSlash.getWithNewlines(s)) {
for (String cs : BackSlash.getWithNewlines(s))
result.add(new StringLocated(cs, null));
}
return new BlocLines(result);
}
@ -150,9 +149,9 @@ public class BlocLines implements Iterable<StringLocated> {
public List<String> getLinesAsStringForSprite() {
final List<String> result = new ArrayList<>();
for (StringLocated s : lines) {
for (StringLocated s : lines)
result.add(s.getString());
}
return result;
}
@ -165,9 +164,9 @@ public class BlocLines implements Iterable<StringLocated> {
}
public StringLocated getFirst() {
if (lines.size() == 0) {
if (lines.size() == 0)
return null;
}
return lines.get(0);
}
@ -192,11 +191,10 @@ public class BlocLines implements Iterable<StringLocated> {
public BlocLines removeEmptyLines() {
final List<StringLocated> copy = new ArrayList<>(lines);
for (final Iterator<StringLocated> it = copy.iterator(); it.hasNext();) {
if (it.next().getString().length() == 0) {
for (final Iterator<StringLocated> it = copy.iterator(); it.hasNext();)
if (it.next().getString().length() == 0)
it.remove();
}
}
return new BlocLines(copy);
}
@ -210,16 +208,16 @@ public class BlocLines implements Iterable<StringLocated> {
// }
public BlocLines removeEmptyColumns() {
if (firstColumnRemovable(lines) == false) {
if (firstColumnRemovable(lines) == false)
return this;
}
final List<StringLocated> copy = new ArrayList<>(lines);
do {
for (int i = 0; i < copy.size(); i++) {
final StringLocated s = copy.get(i);
if (s.getString().length() > 0) {
if (s.getString().length() > 0)
copy.set(i, s.substring(1, s.getString().length()));
}
}
} while (firstColumnRemovable(copy));
return new BlocLines(copy);
@ -228,14 +226,14 @@ public class BlocLines implements Iterable<StringLocated> {
private static boolean firstColumnRemovable(List<StringLocated> data) {
boolean allEmpty = true;
for (StringLocated s : data) {
if (s.getString().length() == 0) {
if (s.getString().length() == 0)
continue;
}
allEmpty = false;
final char c = s.getString().charAt(0);
if (c != ' ' && c != '\t') {
if (c != ' ' && c != '\t')
return false;
}
}
return allEmpty == false;
}
@ -246,9 +244,9 @@ public class BlocLines implements Iterable<StringLocated> {
}
public BlocLines removeStartingAndEnding(String data, int removeAtEnd) {
if (lines.size() == 0) {
if (lines.size() == 0)
return this;
}
final List<StringLocated> copy = new ArrayList<>(lines);
copy.set(0, new StringLocated(data, null));
final int n = copy.size() - 1;
@ -258,9 +256,9 @@ public class BlocLines implements Iterable<StringLocated> {
}
public BlocLines overrideLastLine(String last) {
if (lines.size() == 0) {
if (lines.size() == 0)
return this;
}
final List<StringLocated> copy = new ArrayList<>(lines);
final int n = copy.size() - 1;
final StringLocated currentLast = copy.get(n);
@ -278,9 +276,9 @@ public class BlocLines implements Iterable<StringLocated> {
}
public BlocLines trimSmart(int referenceLine) {
if (lines.size() <= referenceLine) {
if (lines.size() <= referenceLine)
return this;
}
final List<StringLocated> copy = new ArrayList<>(lines);
final int nbStartingSpace = nbStartingSpace(copy.get(referenceLine).getString());
for (int i = referenceLine; i < copy.size(); i++) {
@ -292,9 +290,9 @@ public class BlocLines implements Iterable<StringLocated> {
private static int nbStartingSpace(CharSequence s) {
int nb = 0;
while (nb < s.length() && isSpaceOrTab(s.charAt(nb))) {
while (nb < s.length() && isSpaceOrTab(s.charAt(nb)))
nb++;
}
return nb;
}
@ -331,9 +329,9 @@ public class BlocLines implements Iterable<StringLocated> {
}
public BlocLines eventuallyMoveBracket() {
if (size() < 2) {
if (size() < 2)
return this;
}
final String first = getFirst().getTrimmed().getString();
final String second = getAt(1).getTrimmed().getString();
if (first.endsWith("{") == false && second.equals("{")) {
@ -348,7 +346,7 @@ public class BlocLines implements Iterable<StringLocated> {
public BlocLines eventuallyMoveAllEmptyBracket() {
final List<StringLocated> result = new ArrayList<>();
for (StringLocated line : lines) {
for (StringLocated line : lines)
if (line.getTrimmed().toString().equals("{")) {
if (result.size() > 0) {
final int pos = result.size() - 1;
@ -358,7 +356,7 @@ public class BlocLines implements Iterable<StringLocated> {
} else {
result.add(line);
}
}
return new BlocLines(result);
}

View File

@ -69,7 +69,7 @@ public class CommandSpriteFile extends SingleLineCommand2<TitledDiagram> {
new RegexLeaf("\\$?"), //
new RegexLeaf("NAME", "([-%pLN_]+)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("FILE", "(.*)"), RegexLeaf.end());
new RegexLeaf("FILE", "([^<>%g#]*)"), RegexLeaf.end());
}
@Override
@ -80,37 +80,37 @@ public class CommandSpriteFile extends SingleLineCommand2<TitledDiagram> {
if (src.startsWith("jar:")) {
final String inner = src.substring(4) + ".png";
final InputStream is = SpriteImage.getInternalSprite(inner);
if (is == null) {
if (is == null)
return CommandExecutionResult.error("No such internal sprite: " + inner);
}
sprite = new SpriteImage(SImageIO.read(is));
} else if (src.contains("~")) {
final int idx = src.lastIndexOf("~");
final SFile f = FileSystem.getInstance().getFile(src.substring(0, idx));
if (f.exists() == false) {
if (f.exists() == false)
return CommandExecutionResult.error("Cannot read: " + src);
}
final String name = src.substring(idx + 1);
sprite = getImageFromZip(f, name);
if (sprite == null) {
if (sprite == null)
return CommandExecutionResult.error("Cannot read: " + src);
}
} else {
final SFile f = FileSystem.getInstance().getFile(src);
if (f.exists() == false) {
if (f.exists() == false)
return CommandExecutionResult.error("Cannot read: " + src);
}
if (isSvg(f.getName())) {
final String tmp = FileUtils.readSvg(f);
if (tmp == null) {
if (tmp == null)
return CommandExecutionResult.error("Cannot read: " + src);
}
sprite = new SpriteSvg(tmp);
} else {
final BufferedImage tmp = f.readRasterImageFromFile();
if (tmp == null) {
if (tmp == null)
return CommandExecutionResult.error("Cannot read: " + src);
}
sprite = new SpriteImage(tmp);
}
}

View File

@ -0,0 +1,70 @@
/* ========================================================================
* 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.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.emoji.SvgNanoParser;
public class CommandSpriteSvg extends SingleLineCommand2<TitledDiagram> {
public CommandSpriteSvg() {
super(getRegexConcat());
}
private static IRegex getRegexConcat() {
return RegexConcat.build(CommandSpriteSvg.class.getName(), RegexLeaf.start(), //
new RegexLeaf("sprite"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\$?"), //
new RegexLeaf("NAME", "([-%pLN_]+)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("SVG", "(\\<svg\\b.*\\</svg\\>)"), RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(TitledDiagram system, LineLocation location, RegexResult arg) {
final String svg = arg.get("SVG", 0);
final SvgNanoParser nanoParser = new SvgNanoParser(svg, true);
system.addSprite(arg.get("NAME", 0), nanoParser);
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,85 @@
/* ========================================================================
* 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.command;
import net.sourceforge.plantuml.StringLocated;
import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.emoji.SvgNanoParser;
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
public class CommandSpriteSvgMultiline extends CommandMultilines2<TitledDiagram> {
public CommandSpriteSvgMultiline() {
super(getRegexConcat(), MultilinesStrategy.KEEP_STARTING_QUOTE);
}
private static IRegex getRegexConcat() {
return RegexConcat.build(CommandSpriteSvgMultiline.class.getName(), RegexLeaf.start(), //
new RegexLeaf("sprite"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\$?"), //
new RegexLeaf("NAME", "([-%pLN_]+)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("SVGSTART", "(\\<svg\\b.*)"), //
RegexLeaf.end());
}
@Override
public String getPatternEnd() {
return "(.*\\</svg\\>)$";
}
@Override
protected CommandExecutionResult executeNow(TitledDiagram system, BlocLines lines) throws NoSuchColorException {
final RegexResult line0 = getStartingPattern().matcher(lines.getFirst().getTrimmed().getString());
final String svgStart = line0.get("SVGSTART", 0);
lines = lines.subExtract(1, 0);
final StringBuilder svg = new StringBuilder(svgStart);
for (StringLocated sl : lines)
svg.append(sl.getString());
final SvgNanoParser nanoParser = new SvgNanoParser(svg.toString(), true);
system.addSprite(line0.get("NAME", 0), nanoParser);
return CommandExecutionResult.ok();
}
}

View File

@ -77,7 +77,9 @@ public final class CommonCommands {
final CommandFactorySprite factorySpriteCommand = new CommandFactorySprite();
cmds.add(factorySpriteCommand.createMultiLine(false));
cmds.add(factorySpriteCommand.createSingleLine());
cmds.add(new CommandSpriteSvg());
cmds.add(new CommandSpriteFile());
cmds.add(new CommandSpriteSvgMultiline());
cmds.add(new CommandStyleMultilinesCSS());
cmds.add(new CommandStyleImport());

View File

@ -44,17 +44,17 @@ public enum MultilinesStrategy {
REMOVE_STARTING_QUOTE, KEEP_STARTING_QUOTE;
public void cleanList(List<StringLocated> lines) {
if (this == REMOVE_STARTING_QUOTE) {
if (this == REMOVE_STARTING_QUOTE)
filterQuote(lines);
}
}
private void filterQuote(List<StringLocated> lines) {
for (final Iterator<StringLocated> it = lines.iterator(); it.hasNext();) {
final StringLocated s = it.next();
if (hasStartingQuote(s)) {
if (hasStartingQuote(s))
it.remove();
}
}
}

View File

@ -61,6 +61,8 @@ public class Dedications {
"1182423723677118831606503500858825217076578422970565964857326298418401529955036896808663335300684244453386039908536275400945824932191521017102701344437753036730900076162922741167523337650578479960119614237031234925702200473053235777")));
all.add(secret(3, "514816d583044efbd336882227deb822194ff63e3bdc3cf707a01f17770d5a6a", new BigInteger(
"538955952645999836068094511687012232127213955837942782605199622268460518023083462090291844640318324475656060087513198129259364840841077651829017347845508167869708224054456044836844382437974410757740941102771969965334031780041648873")));
all.add(secret(1, "ae8a7cf3997ccd6418866fc59e596502e1bd1c0265bba2fc380ad7f51c76518f", new BigInteger(
"987988542836850639056829173787067531749177506648884857100630852970876999799588072360773169026225182488073794585127241896588994816566037813451743416913613428321215803586563629080034406083114565732322220091545330060636171674602040157")));
} catch (Throwable t) {
t.printStackTrace();
}

View File

@ -63,6 +63,8 @@ import net.sourceforge.plantuml.descdiagram.command.CommandCreateElementMultilin
import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement;
import net.sourceforge.plantuml.descdiagram.command.CommandNewpage;
import net.sourceforge.plantuml.descdiagram.command.CommandPackageWithUSymbol;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateJson;
import net.sourceforge.plantuml.objectdiagram.command.CommandCreateMap;
public class DescriptionDiagramFactory extends PSystemCommandFactory {
@ -116,6 +118,8 @@ public class DescriptionDiagramFactory extends PSystemCommandFactory {
cmds.add(factoryNoteOnEntityCommand.createMultiLine(false));
cmds.add(factoryNoteCommand.createMultiLine(false));
cmds.add(new CommandCreateMap());
cmds.add(new CommandCreateJson());
// cmds.add(new CommandHideShowSpecificClass());
cmds.add(new CommandArchimate());

View File

@ -1,6 +1,5 @@
package net.sourceforge.plantuml.emoji;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -11,26 +10,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.emoji.data.Dummy;
import net.sourceforge.plantuml.openiconic.SvgPath;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.ColorChangerMonochrome;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorNone;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorSimple;
// Emojji from https://twemoji.twitter.com/
// Shorcut from https://api.github.com/emojis
public class Emoji {
private final static Map<String, Emoji> ALL = new HashMap<>();
static {
@ -49,9 +37,8 @@ public class Emoji {
return Collections.unmodifiableMap(new TreeMap<>(ALL));
}
private final List<String> data = new ArrayList<>();
private int minGray = 999;
private int maxGray = -1;
private SvgNanoParser nano;
private final String unicode;
private final String shortcut;
@ -83,34 +70,17 @@ public class Emoji {
return ALL.get(name.toLowerCase());
}
private String extractData(String name, String s) {
final Pattern p = Pattern.compile(name + "=\"([^\"]+)\"");
final Matcher m = p.matcher(s);
if (m.find())
return m.group(1);
return null;
}
private synchronized void loadIfNeed() throws IOException {
if (data.size() > 0)
if (nano != null)
return;
final List<String> data = new ArrayList<String>();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(Dummy.class.getResourceAsStream(unicode + ".svg")))) {
final String singleLine = br.readLine();
final Pattern p = Pattern.compile("\\<[^<>]+\\>");
final Matcher m = p.matcher(singleLine);
while (m.find()) {
final String s = m.group(0);
if (s.contains("<path") || s.contains("<g ") || s.contains("<g>") || s.contains("</g>")
|| s.contains("<circle ") || s.contains("<ellipse "))
data.add(s);
else
System.err.println("???=" + s);
}
data.add(singleLine);
}
this.nano = new SvgNanoParser(data, false);
}
public void drawU(UGraphic ug, double scale, HColor colorForMonochrome) {
@ -119,249 +89,7 @@ public class Emoji {
} catch (IOException e) {
e.printStackTrace();
}
UGraphicWithScale ugs = new UGraphicWithScale(ug, scale);
synchronized (this) {
if (colorForMonochrome != null && maxGray == -1)
computeMinMaxGray();
}
final List<UGraphicWithScale> stack = new ArrayList<>();
for (String s : data) {
if (s.contains("<path ")) {
drawPath(ugs, s, colorForMonochrome);
} else if (s.contains("</g>")) {
ugs = stack.remove(0);
} else if (s.contains("<g>")) {
stack.add(0, ugs);
} else if (s.contains("<g ")) {
stack.add(0, ugs);
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
} else if (s.contains("<circle ")) {
drawCircle(ugs, s, colorForMonochrome);
} else if (s.contains("<ellipse ")) {
drawEllipse(ugs, s, colorForMonochrome);
} else {
System.err.println("**?=" + s);
}
}
}
private void computeMinMaxGray() {
for (String s : data) {
if (s.contains("<path ") || s.contains("<g ") || s.contains("<circle ") || s.contains("<ellipse ")) {
final HColor color = justExtractColor(s);
if (color != null) {
final int gray = getGray(color);
minGray = Math.min(minGray, gray);
maxGray = Math.max(maxGray, gray);
}
} else {
// Nothing
}
}
}
private int getGray(HColor col) {
final Color tmp = new ColorChangerMonochrome().getChangedColor(col);
return tmp.getGreen();
}
private UGraphicWithScale applyFill(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
final String fillString = extractData("fill", s);
if (fillString == null)
return ugs;
if (fillString.equals("none")) {
final String strokeString = extractData("stroke", s);
if (strokeString == null)
return ugs;
ugs = ugs.apply(new HColorNone().bg());
final HColor stroke = getTrueColor(strokeString, colorForMonochrome);
ugs = ugs.apply(stroke);
final String strokeWidth = extractData("stroke-width", s);
if (strokeWidth != null) {
ugs = ugs.apply(new UStroke(Double.parseDouble(strokeWidth)));
}
} else {
final HColor fill = getTrueColor(fillString, colorForMonochrome);
ugs = ugs.apply(fill).apply(fill.bg());
}
return ugs;
}
private HColor justExtractColor(String s) {
final String fillString = extractData("fill", s);
if (fillString == null)
return null;
if (fillString.equals("none")) {
final String strokeString = extractData("stroke", s);
if (strokeString == null)
return null;
final HColor stroke = getTrueColor(strokeString, null);
return stroke;
} else {
final HColor fill = getTrueColor(fillString, null);
return fill;
}
}
private HColor getTrueColor(String code, HColor colorForMonochrome) {
final HColorSimple result = (HColorSimple) HColorSet.instance().getColorOrWhite(code);
if (colorForMonochrome == null)
return result;
final HColorSimple color = (HColorSimple) colorForMonochrome;
if (color.isGray())
return result.asMonochrome();
return result.asMonochrome(color, this.minGray, this.maxGray);
}
private void drawCircle(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final double scalex = ugs.getAffineTransform().getScaleX();
final double scaley = ugs.getAffineTransform().getScaleY();
final double deltax = ugs.getAffineTransform().getTranslateX();
final double deltay = ugs.getAffineTransform().getTranslateY();
final double cx = Double.parseDouble(extractData("cx", s)) * scalex;
final double cy = Double.parseDouble(extractData("cy", s)) * scaley;
final double rx = Double.parseDouble(extractData("r", s)) * scalex;
final double ry = Double.parseDouble(extractData("r", s)) * scaley;
final UTranslate translate = new UTranslate(deltax + cx - rx, deltay + cy - ry);
ugs.apply(translate).draw(new UEllipse(rx * 2, ry * 2));
}
private void drawEllipse(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final double scalex = ugs.getAffineTransform().getScaleX();
final double scaley = ugs.getAffineTransform().getScaleY();
final double deltax = ugs.getAffineTransform().getTranslateX();
final double deltay = ugs.getAffineTransform().getTranslateY();
final double cx = Double.parseDouble(extractData("cx", s)) * scalex;
final double cy = Double.parseDouble(extractData("cy", s)) * scaley;
final double rx = Double.parseDouble(extractData("rx", s)) * scalex;
final double ry = Double.parseDouble(extractData("ry", s)) * scaley;
final UTranslate translate = new UTranslate(deltax + cx - rx, deltay + cy - ry);
ugs.apply(translate).draw(new UEllipse(rx * 2, ry * 2));
}
private void drawPath(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
s = s.replace("id=\"", "ID=\"");
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final int x1 = s.indexOf("d=\"");
final int x2 = s.indexOf('"', x1 + 3);
final String tmp = s.substring(x1 + 3, x2);
final SvgPath svgPath = new SvgPath(tmp);
svgPath.drawMe(ugs.getUg(), ugs.getAffineTransform());
}
private UGraphicWithScale applyTransform(UGraphicWithScale ugs, String s) {
final String transform = extractData("transform", s);
if (transform == null)
return ugs;
if (transform.contains("rotate("))
return applyRotate(ugs, transform);
if (transform.contains("matrix("))
return applyMatrix(ugs, transform);
final double[] scale = getScale(transform);
final UTranslate translate = getTranslate(transform);
ugs = ugs.applyTranslate(translate.getDx(), translate.getDy());
return ugs.applyScale(scale[0], scale[1]);
}
private UGraphicWithScale applyMatrix(UGraphicWithScale ugs, final String transform) {
final Pattern p3 = Pattern.compile(
"matrix\\(([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
final double v1 = Double.parseDouble(m3.group(1));
final double v2 = Double.parseDouble(m3.group(2));
final double v3 = Double.parseDouble(m3.group(3));
final double v4 = Double.parseDouble(m3.group(4));
final double v5 = Double.parseDouble(m3.group(5));
final double v6 = Double.parseDouble(m3.group(6));
ugs = ugs.applyMatrix(v1, v2, v3, v4, v5, v6);
} else
System.err.println("WARNING: " + transform);
return ugs;
}
private UGraphicWithScale applyRotate(UGraphicWithScale ugs, final String transform) {
final Pattern p3 = Pattern.compile("rotate\\(([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
final double angle = Double.parseDouble(m3.group(1));
final double x = Double.parseDouble(m3.group(2));
final double y = Double.parseDouble(m3.group(3));
ugs = ugs.applyRotate(angle, x, y);
} else
System.err.println("WARNING: " + transform);
return ugs;
}
private UTranslate getTranslate(String transform) {
double x = 0;
double y = 0;
final Pattern p3 = Pattern.compile("translate\\(([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
x = Double.parseDouble(m3.group(1));
y = Double.parseDouble(m3.group(2));
} else {
final Pattern p4 = Pattern.compile("translate\\(([-.0-9]+)\\)");
final Matcher m4 = p4.matcher(transform);
if (m4.find()) {
x = Double.parseDouble(m4.group(1));
y = Double.parseDouble(m4.group(1));
}
}
return new UTranslate(x, y);
}
private double[] getScale(String transform) {
final double scale[] = new double[] { 1, 1 };
final Pattern p1 = Pattern.compile("scale\\(([-.0-9]+)\\)");
final Matcher m1 = p1.matcher(transform);
if (m1.find()) {
scale[0] = Double.parseDouble(m1.group(1));
scale[1] = scale[0];
} else {
final Pattern p2 = Pattern.compile("scale\\(([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m2 = p2.matcher(transform);
if (m2.find()) {
scale[0] = Double.parseDouble(m2.group(1));
scale[1] = Double.parseDouble(m2.group(2));
}
}
return scale;
nano.drawU(ug, scale, colorForMonochrome);
}
public String getShortcut() {

View File

@ -0,0 +1,110 @@
/* ========================================================================
* 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.emoji;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.security.SImageIO;
import net.sourceforge.plantuml.sprite.Sprite;
import net.sourceforge.plantuml.ugraphic.AffineTransformType;
import net.sourceforge.plantuml.ugraphic.PixelImage;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.ColorMapperMonochrome;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class SpriteSvgNanoParser implements Sprite {
private final UImage img;
public SpriteSvgNanoParser(BufferedImage img) {
this.img = new UImage(new PixelImage(Objects.requireNonNull(img), AffineTransformType.TYPE_BILINEAR));
}
public TextBlock asTextBlock(final HColor color, final double scale, final ColorMapper colorMapper) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
if (colorMapper instanceof ColorMapperMonochrome) {
ug.draw(img.monochrome().scale(scale));
} else if (color == null)
ug.draw(img.scale(scale));
else
ug.draw(img.muteColor(colorMapper.toColor(color)).scale(scale));
// ug.draw(img.muteColor(((HColorSimple) color).getColor999()).scale(scale));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return new Dimension2DDouble(img.getWidth() * scale, img.getHeight() * scale);
}
};
}
public static Sprite fromInternal(String name) {
if (name.endsWith(".png"))
throw new IllegalArgumentException();
final InputStream is = getInternalSprite(name + ".png");
if (is == null)
return null;
try {
return new SpriteSvgNanoParser(SImageIO.read(is));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static InputStream getInternalSprite(final String inner) {
final String path = "/sprites/" + inner;
final InputStream is = SpriteSvgNanoParser.class.getResourceAsStream(path);
return is;
}
}

View File

@ -0,0 +1,335 @@
package net.sourceforge.plantuml.emoji;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.openiconic.SvgPath;
import net.sourceforge.plantuml.sprite.Sprite;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.ColorChangerMonochrome;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorNone;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorSimple;
// Emojji from https://twemoji.twitter.com/
// Shorcut from https://api.github.com/emojis
public class SvgNanoParser implements Sprite {
private final List<String> data = new ArrayList<>();
private int minGray = 999;
private int maxGray = -1;
private final String svgStart;
private final boolean keepColors;
private String extractData(String name, String s) {
final Pattern p = Pattern.compile(name + "=\"([^\"]+)\"");
final Matcher m = p.matcher(s);
if (m.find())
return m.group(1);
return null;
}
public SvgNanoParser(String svg, boolean keepColors) {
this(Collections.singletonList(svg), keepColors);
}
public SvgNanoParser(List<String> svg, boolean keepColors) {
this.svgStart = svg.get(0);
this.keepColors = keepColors;
for (String singleLine : svg) {
final Pattern p = Pattern.compile("\\<[^<>]+\\>");
final Matcher m = p.matcher(singleLine);
while (m.find()) {
final String s = m.group(0);
if (s.contains("<path") || s.contains("<g ") || s.contains("<g>") || s.contains("</g>")
|| s.contains("<circle ") || s.contains("<ellipse "))
data.add(s);
else
System.err.println("???=" + s);
}
}
}
public void drawU(UGraphic ug, double scale, HColor colorForMonochrome) {
UGraphicWithScale ugs = new UGraphicWithScale(ug, scale);
synchronized (this) {
if (colorForMonochrome != null && maxGray == -1)
computeMinMaxGray();
}
final List<UGraphicWithScale> stack = new ArrayList<>();
for (String s : data) {
if (s.contains("<path ")) {
drawPath(ugs, s, colorForMonochrome);
} else if (s.contains("</g>")) {
ugs = stack.remove(0);
} else if (s.contains("<g>")) {
stack.add(0, ugs);
} else if (s.contains("<g ")) {
stack.add(0, ugs);
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
} else if (s.contains("<circle ")) {
drawCircle(ugs, s, colorForMonochrome);
} else if (s.contains("<ellipse ")) {
drawEllipse(ugs, s, colorForMonochrome);
} else {
System.err.println("**?=" + s);
}
}
}
private void computeMinMaxGray() {
for (String s : data) {
if (s.contains("<path ") || s.contains("<g ") || s.contains("<circle ") || s.contains("<ellipse ")) {
final HColor color = justExtractColor(s);
if (color != null) {
final int gray = getGray(color);
minGray = Math.min(minGray, gray);
maxGray = Math.max(maxGray, gray);
}
} else {
// Nothing
}
}
}
private int getGray(HColor col) {
final Color tmp = new ColorChangerMonochrome().getChangedColor(col);
return tmp.getGreen();
}
private UGraphicWithScale applyFill(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
final String fillString = extractData("fill", s);
if (fillString == null)
return ugs;
if (fillString.equals("none")) {
final String strokeString = extractData("stroke", s);
if (strokeString == null)
return ugs;
ugs = ugs.apply(new HColorNone().bg());
final HColor stroke = getTrueColor(strokeString, colorForMonochrome);
ugs = ugs.apply(stroke);
final String strokeWidth = extractData("stroke-width", s);
if (strokeWidth != null) {
ugs = ugs.apply(new UStroke(Double.parseDouble(strokeWidth)));
}
} else {
final HColor fill = getTrueColor(fillString, colorForMonochrome);
ugs = ugs.apply(fill).apply(fill.bg());
}
return ugs;
}
private HColor justExtractColor(String s) {
final String fillString = extractData("fill", s);
if (fillString == null)
return null;
if (fillString.equals("none")) {
final String strokeString = extractData("stroke", s);
if (strokeString == null)
return null;
final HColor stroke = getTrueColor(strokeString, null);
return stroke;
} else {
final HColor fill = getTrueColor(fillString, null);
return fill;
}
}
private HColor getTrueColor(String code, HColor colorForMonochrome) {
final HColorSimple result = (HColorSimple) HColorSet.instance().getColorOrWhite(code);
if (colorForMonochrome == null)
return result;
final HColorSimple color = (HColorSimple) colorForMonochrome;
if (color.isGray())
return result.asMonochrome();
return result.asMonochrome(color, this.minGray, this.maxGray);
}
private void drawCircle(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final double scalex = ugs.getAffineTransform().getScaleX();
final double scaley = ugs.getAffineTransform().getScaleY();
final double deltax = ugs.getAffineTransform().getTranslateX();
final double deltay = ugs.getAffineTransform().getTranslateY();
final double cx = Double.parseDouble(extractData("cx", s)) * scalex;
final double cy = Double.parseDouble(extractData("cy", s)) * scaley;
final double rx = Double.parseDouble(extractData("r", s)) * scalex;
final double ry = Double.parseDouble(extractData("r", s)) * scaley;
final UTranslate translate = new UTranslate(deltax + cx - rx, deltay + cy - ry);
ugs.apply(translate).draw(new UEllipse(rx * 2, ry * 2));
}
private void drawEllipse(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final double scalex = ugs.getAffineTransform().getScaleX();
final double scaley = ugs.getAffineTransform().getScaleY();
final double deltax = ugs.getAffineTransform().getTranslateX();
final double deltay = ugs.getAffineTransform().getTranslateY();
final double cx = Double.parseDouble(extractData("cx", s)) * scalex;
final double cy = Double.parseDouble(extractData("cy", s)) * scaley;
final double rx = Double.parseDouble(extractData("rx", s)) * scalex;
final double ry = Double.parseDouble(extractData("ry", s)) * scaley;
final UTranslate translate = new UTranslate(deltax + cx - rx, deltay + cy - ry);
ugs.apply(translate).draw(new UEllipse(rx * 2, ry * 2));
}
private void drawPath(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {
s = s.replace("id=\"", "ID=\"");
ugs = applyFill(ugs, s, colorForMonochrome);
ugs = applyTransform(ugs, s);
final int x1 = s.indexOf("d=\"");
final int x2 = s.indexOf('"', x1 + 3);
final String tmp = s.substring(x1 + 3, x2);
final SvgPath svgPath = new SvgPath(tmp);
svgPath.drawMe(ugs.getUg(), ugs.getAffineTransform());
}
private UGraphicWithScale applyTransform(UGraphicWithScale ugs, String s) {
final String transform = extractData("transform", s);
if (transform == null)
return ugs;
if (transform.contains("rotate("))
return applyRotate(ugs, transform);
if (transform.contains("matrix("))
return applyMatrix(ugs, transform);
final double[] scale = getScale(transform);
final UTranslate translate = getTranslate(transform);
ugs = ugs.applyTranslate(translate.getDx(), translate.getDy());
return ugs.applyScale(scale[0], scale[1]);
}
private UGraphicWithScale applyMatrix(UGraphicWithScale ugs, final String transform) {
final Pattern p3 = Pattern.compile(
"matrix\\(([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
final double v1 = Double.parseDouble(m3.group(1));
final double v2 = Double.parseDouble(m3.group(2));
final double v3 = Double.parseDouble(m3.group(3));
final double v4 = Double.parseDouble(m3.group(4));
final double v5 = Double.parseDouble(m3.group(5));
final double v6 = Double.parseDouble(m3.group(6));
ugs = ugs.applyMatrix(v1, v2, v3, v4, v5, v6);
} else
System.err.println("WARNING: " + transform);
return ugs;
}
private UGraphicWithScale applyRotate(UGraphicWithScale ugs, final String transform) {
final Pattern p3 = Pattern.compile("rotate\\(([-.0-9]+)[ ,]+([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
final double angle = Double.parseDouble(m3.group(1));
final double x = Double.parseDouble(m3.group(2));
final double y = Double.parseDouble(m3.group(3));
ugs = ugs.applyRotate(angle, x, y);
} else
System.err.println("WARNING: " + transform);
return ugs;
}
private UTranslate getTranslate(String transform) {
double x = 0;
double y = 0;
final Pattern p3 = Pattern.compile("translate\\(([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m3 = p3.matcher(transform);
if (m3.find()) {
x = Double.parseDouble(m3.group(1));
y = Double.parseDouble(m3.group(2));
} else {
final Pattern p4 = Pattern.compile("translate\\(([-.0-9]+)\\)");
final Matcher m4 = p4.matcher(transform);
if (m4.find()) {
x = Double.parseDouble(m4.group(1));
y = Double.parseDouble(m4.group(1));
}
}
return new UTranslate(x, y);
}
private double[] getScale(String transform) {
final double scale[] = new double[] { 1, 1 };
final Pattern p1 = Pattern.compile("scale\\(([-.0-9]+)\\)");
final Matcher m1 = p1.matcher(transform);
if (m1.find()) {
scale[0] = Double.parseDouble(m1.group(1));
scale[1] = scale[0];
} else {
final Pattern p2 = Pattern.compile("scale\\(([-.0-9]+)[ ,]+([-.0-9]+)\\)");
final Matcher m2 = p2.matcher(transform);
if (m2.find()) {
scale[0] = Double.parseDouble(m2.group(1));
scale[1] = Double.parseDouble(m2.group(2));
}
}
return scale;
}
@Override
public TextBlock asTextBlock(final HColor color, final double scale, final ColorMapper colorMapper) {
final UImageSvg data = new UImageSvg(svgStart, scale);
final double width = data.getWidth();
final double height = data.getHeight();
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
SvgNanoParser.this.drawU(ug, scale, keepColors ? null : color);
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return new Dimension2DDouble(width, height);
}
};
}
}

View File

@ -38,6 +38,7 @@ package net.sourceforge.plantuml.objectdiagram.command;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.StringLocated;
import net.sourceforge.plantuml.UrlBuilder;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.CommandMultilines2;
@ -61,11 +62,10 @@ 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.objectdiagram.AbstractClassOrObjectDiagram;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
public class CommandCreateMap extends CommandMultilines2<AbstractClassOrObjectDiagram> {
public class CommandCreateMap extends CommandMultilines2<AbstractEntityDiagram> {
public CommandCreateMap() {
super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE);
@ -100,7 +100,7 @@ public class CommandCreateMap extends CommandMultilines2<AbstractClassOrObjectDi
}
@Override
protected CommandExecutionResult executeNow(AbstractClassOrObjectDiagram diagram, BlocLines lines)
protected CommandExecutionResult executeNow(AbstractEntityDiagram diagram, BlocLines lines)
throws NoSuchColorException {
lines = lines.trim().removeEmptyLines();
final RegexResult line0 = getStartingPattern().matcher(lines.getFirst().getTrimmed().getString());
@ -137,7 +137,7 @@ public class CommandCreateMap extends CommandMultilines2<AbstractClassOrObjectDi
return CommandExecutionResult.ok();
}
private IEntity executeArg0(AbstractClassOrObjectDiagram diagram, RegexResult line0) throws NoSuchColorException {
private IEntity executeArg0(AbstractEntityDiagram diagram, RegexResult line0) throws NoSuchColorException {
final String name = line0.get("NAME", 1);
final Ident ident = diagram.buildLeafIdent(name);
final Code code = diagram.V1972() ? ident : diagram.buildCode(name);

View File

@ -66,15 +66,12 @@ public class SpriteImage implements Sprite {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
if (colorMapper instanceof ColorMapperMonochrome) {
if (colorMapper instanceof ColorMapperMonochrome)
ug.draw(img.monochrome().scale(scale));
} else if (color == null)
else if (color == null)
ug.draw(img.scale(scale));
else
ug.draw(img.muteColor(colorMapper.toColor(color)).scale(scale));
// ug.draw(img.muteColor(((HColorSimple) color).getColor999()).scale(scale));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {

View File

@ -48,12 +48,10 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
public class SpriteSvg implements Sprite {
// private final UImageSvg img;
private final String svg;
public SpriteSvg(String svg) {
this.svg = svg;
// this.img = new UImageSvg(new SvgString(svg, 1));
}
public TextBlock asTextBlock(final HColor color, final double scale, ColorMapper colorMapper) {

View File

@ -49,6 +49,7 @@ import net.sourceforge.plantuml.graphic.color.ColorType;
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.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster;
@ -70,8 +71,8 @@ public class EntityImagePort extends AbstractEntityImageBorder {
this.sname = sname;
}
private StyleSignatureBasic getSignature() {
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.boundary);
private StyleSignature getSignature() {
return StyleSignatureBasic.of(SName.root, SName.element, sname, SName.boundary).withTOBECHANGED(getStereo());
}
private boolean upPosition() {
@ -107,17 +108,21 @@ public class EntityImagePort extends AbstractEntityImageBorder {
desc.drawU(ug.apply(new UTranslate(x, y)));
HColor backcolor = getEntity().getColors().getColor(ColorType.BACK);
final Style style = getSignature().getMergedStyle(getSkinParam().getCurrentStyleBuilder());
final HColor borderColor = style.value(PName.LineColor).asColor(getSkinParam().getThemeStyle(),
HColor backcolor = getEntity().getColors().getColor(ColorType.BACK);
HColor borderColor = getEntity().getColors().getColor(ColorType.LINE);
if (borderColor == null)
borderColor = style.value(PName.LineColor).asColor(getSkinParam().getThemeStyle(),
getSkinParam().getIHtmlColorSet());
if (backcolor == null)
backcolor = style.value(PName.BackGroundColor).asColor(getSkinParam().getThemeStyle(),
getSkinParam().getIHtmlColorSet());
ug = ug.apply(backcolor);
ug = ug.apply(getUStroke()).apply(borderColor.bg());
ug = ug.apply(borderColor);
ug = ug.apply(getUStroke()).apply(backcolor.bg());
drawSymbol(ug);
}

View File

@ -80,7 +80,7 @@ public class Version {
}
public static int beta() {
final int beta = 6;
final int beta = 8;
return beta;
}