mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 10:59:01 +00:00
version 1.2020.13
This commit is contained in:
parent
301fd18b2f
commit
37a6f82e35
2
pom.xml
2
pom.xml
@ -35,7 +35,7 @@
|
||||
|
||||
<groupId>net.sourceforge.plantuml</groupId>
|
||||
<artifactId>plantuml</artifactId>
|
||||
<version>1.2020.13-SNAPSHOT</version>
|
||||
<version>1.2020.14-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PlantUML</name>
|
||||
|
56
src/net/sourceforge/plantuml/ComponentStyle.java
Normal file
56
src/net/sourceforge/plantuml/ComponentStyle.java
Normal file
@ -0,0 +1,56 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, 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;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.USymbol;
|
||||
|
||||
public enum ComponentStyle {
|
||||
|
||||
UML1, UML2, RECTANGLE;
|
||||
|
||||
public USymbol toSymbol() {
|
||||
switch (this) {
|
||||
case UML1:
|
||||
return USymbol.COMPONENT1;
|
||||
case UML2:
|
||||
return USymbol.COMPONENT2;
|
||||
case RECTANGLE:
|
||||
return USymbol.RECTANGLE;
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
}
|
@ -98,7 +98,7 @@ public interface ISkinParam extends ISkinSimple {
|
||||
|
||||
public PackageStyle getPackageStyle();
|
||||
|
||||
public boolean useUml2ForComponent();
|
||||
public ComponentStyle componentStyle();
|
||||
|
||||
public boolean stereotypePositionTop();
|
||||
|
||||
|
@ -807,12 +807,16 @@ public class SkinParam implements ISkinParam {
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean useUml2ForComponent() {
|
||||
public ComponentStyle componentStyle() {
|
||||
if (strictUmlStyle()) {
|
||||
return true;
|
||||
return ComponentStyle.UML2;
|
||||
}
|
||||
final String value = getValue("componentstyle");
|
||||
return "uml2".equalsIgnoreCase(value);
|
||||
if ("uml2".equalsIgnoreCase(value))
|
||||
return ComponentStyle.UML2;
|
||||
if ("rectangle".equalsIgnoreCase(value))
|
||||
return ComponentStyle.RECTANGLE;
|
||||
return ComponentStyle.UML1;
|
||||
}
|
||||
|
||||
public boolean stereotypePositionTop() {
|
||||
|
@ -132,8 +132,8 @@ public class SkinParamDelegator implements ISkinParam {
|
||||
return skinParam.getSprite(name);
|
||||
}
|
||||
|
||||
public boolean useUml2ForComponent() {
|
||||
return skinParam.useUml2ForComponent();
|
||||
public ComponentStyle componentStyle() {
|
||||
return skinParam.componentStyle();
|
||||
}
|
||||
|
||||
public boolean stereotypePositionTop() {
|
||||
|
@ -144,6 +144,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
final Code namespace = buildCode(namespaceString);
|
||||
final Display tmp = Display.getWithNewlines(namespaceString);
|
||||
final Ident newIdLong = buildLeafIdentSpecial(namespaceString);
|
||||
// final Ident newIdLong = buildLeafIdentSpecial2(namespaceString);
|
||||
gotoGroupExternal(newIdLong, namespace, tmp, namespace, GroupType.PACKAGE, getRootGroup());
|
||||
}
|
||||
final Display tmpDisplay;
|
||||
@ -212,8 +213,8 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram {
|
||||
margin1 = 0;
|
||||
margin2 = 10;
|
||||
}
|
||||
final ImageBuilder imageBuilder = ImageBuilder.buildD(getSkinParam(), ClockwiseTopRightBottomLeft.margin1margin2((double) margin1, (double) margin2), null, null,
|
||||
null, (double) 1);
|
||||
final ImageBuilder imageBuilder = ImageBuilder.buildD(getSkinParam(),
|
||||
ClockwiseTopRightBottomLeft.margin1margin2(margin1, margin2), null, null, null, 1);
|
||||
imageBuilder.setUDrawable(fullLayout);
|
||||
return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed(), os);
|
||||
}
|
||||
|
@ -39,10 +39,7 @@ import java.awt.Color;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.FileSystem;
|
||||
@ -88,8 +85,9 @@ public class AtomImg extends AbstractAtom implements Atom {
|
||||
if (im == null) {
|
||||
im = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
return new AtomImg(new UImage(new PixelImage(im, AffineTransformType.TYPE_NEAREST_NEIGHBOR))
|
||||
.scale(scale).getImage(1), 1, null, null);
|
||||
return new AtomImg(
|
||||
new UImage(new PixelImage(im, AffineTransformType.TYPE_NEAREST_NEIGHBOR)).scale(scale).getImage(1), 1,
|
||||
null, null);
|
||||
}
|
||||
|
||||
public static Atom create(String src, ImgValign valign, int vspace, double scale, Url url) {
|
||||
@ -171,42 +169,13 @@ public class AtomImg extends AbstractAtom implements Atom {
|
||||
if (source == null) {
|
||||
return AtomText.create("(Cannot decode SVG: " + text + ")", fc);
|
||||
}
|
||||
final byte[] read = getFile(source);
|
||||
final byte[] read = source.getBytes();
|
||||
if (read == null) {
|
||||
return AtomText.create("(Cannot decode SVG: " + text + ")", fc);
|
||||
}
|
||||
return new AtomImgSvg(new TileImageSvg(new String(read, "UTF-8")));
|
||||
}
|
||||
|
||||
// Added by Alain Corbiere
|
||||
private static byte[] getFile(SURL url) {
|
||||
try {
|
||||
InputStream input = null;
|
||||
try {
|
||||
final URLConnection connection = url.openConnection();
|
||||
if (connection == null) {
|
||||
return null;
|
||||
}
|
||||
input = connection.getInputStream();
|
||||
final ByteArrayOutputStream image = new ByteArrayOutputStream();
|
||||
final byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
while ((read = input.read(buffer)) > 0) {
|
||||
image.write(buffer, 0, read);
|
||||
}
|
||||
image.close();
|
||||
return image.toByteArray();
|
||||
} finally {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// End
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
@ -221,8 +190,8 @@ public class AtomImg extends AbstractAtom implements Atom {
|
||||
if (url != null) {
|
||||
ug.startUrl(url);
|
||||
}
|
||||
ug.draw(new UImage(new PixelImage(image, AffineTransformType.TYPE_BILINEAR))
|
||||
.withRawFileName(rawFileName).scale(scale));
|
||||
ug.draw(new UImage(new PixelImage(image, AffineTransformType.TYPE_BILINEAR)).withRawFileName(rawFileName)
|
||||
.scale(scale));
|
||||
if (url != null) {
|
||||
ug.closeUrl();
|
||||
}
|
||||
|
@ -220,12 +220,15 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
|
||||
|
||||
final public Ident buildLeafIdentSpecial(String id) {
|
||||
return buildFullyQualified(id);
|
||||
// if (namespaceSeparator != null) {
|
||||
// if (id.contains(namespaceSeparator)) {
|
||||
// return Ident.empty().add(id, namespaceSeparator);
|
||||
// }
|
||||
// }
|
||||
// return getLastID().add(id, namespaceSeparator);
|
||||
}
|
||||
|
||||
private Ident buildLeafIdentSpecialUnused(String id) {
|
||||
// if (namespaceSeparator != null) {
|
||||
// if (id.contains(namespaceSeparator)) {
|
||||
return Ident.empty().add(id, ".");
|
||||
// }
|
||||
// }
|
||||
// return getLastID().add(id, namespaceSeparator);
|
||||
}
|
||||
|
||||
final public Ident buildFullyQualified(String id) {
|
||||
|
@ -75,6 +75,11 @@ public class GroupRoot implements IGroup {
|
||||
return Collections.unmodifiableCollection(result);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ROOT";
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return true;
|
||||
|
@ -237,6 +237,11 @@ public final class EntityFactory {
|
||||
if (groupType == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
for (Entry<Ident, IGroup> ent : groups2.entrySet()) {
|
||||
if (ent.getKey().equals(ident)) {
|
||||
return ent.getValue();
|
||||
}
|
||||
}
|
||||
final Bodier bodier = new BodierImpl(null, hides);
|
||||
final EntityImpl result = new EntityImpl(ident, code, this, bodier, parentContainer, groupType, namespace,
|
||||
namespaceSeparator, rawLayout);
|
||||
|
@ -268,7 +268,7 @@ final public class EntityImpl implements ILeaf, IGroup {
|
||||
// + getUid();
|
||||
if (entityFactory.namespaceSeparator.V1972())
|
||||
return getUid() + " " + ident + " " + display + "(" + leafType + ")[" + groupType + "]";
|
||||
return super.toString() + code + ident + " " + display + "(" + leafType + ")[" + groupType + "] " + getUid();
|
||||
return "EntityImpl " + code + ident + " " + display + "(" + leafType + ")[" + groupType + "] " + getUid();
|
||||
}
|
||||
|
||||
public final Url getUrl99() {
|
||||
@ -802,7 +802,7 @@ final public class EntityImpl implements ILeaf, IGroup {
|
||||
public IGroup getOriginalGroup() {
|
||||
return originalGroup;
|
||||
}
|
||||
|
||||
|
||||
private boolean together;
|
||||
|
||||
public void setThisIsTogether() {
|
||||
|
@ -35,6 +35,7 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.descdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.ComponentStyle;
|
||||
import net.sourceforge.plantuml.ISkinSimple;
|
||||
import net.sourceforge.plantuml.StringUtils;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
@ -74,14 +75,14 @@ public class DescriptionDiagram extends AbstractEntityDiagram {
|
||||
if (type == null) {
|
||||
String codeString = code.getName();
|
||||
if (codeString.startsWith("[") && codeString.endsWith("]")) {
|
||||
final USymbol sym = getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1;
|
||||
final USymbol sym = getSkinParam().componentStyle().toSymbol() ;
|
||||
final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
|
||||
return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, sym);
|
||||
}
|
||||
if (codeString.startsWith(":") && codeString.endsWith(":")) {
|
||||
final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:");
|
||||
return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, getSkinParam()
|
||||
.getActorStyle().getUSymbol());
|
||||
return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION,
|
||||
getSkinParam().getActorStyle().getUSymbol());
|
||||
}
|
||||
if (codeString.startsWith("()")) {
|
||||
codeString = StringUtils.trin(codeString.substring(2));
|
||||
|
@ -291,7 +291,7 @@ public class CommandLinkElement extends SingleLineCommand2<DescriptionDiagram> {
|
||||
return getOrCreateLeaf1972(diagram, ident3, code3, LeafType.DESCRIPTION,
|
||||
diagram.getSkinParam().getActorStyle().getUSymbol(), pure);
|
||||
} else if (codeChar == '[') {
|
||||
final USymbol sym = diagram.getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1;
|
||||
final USymbol sym = diagram.getSkinParam().componentStyle().toSymbol();
|
||||
return getOrCreateLeaf1972(diagram, ident3, code3, LeafType.DESCRIPTION, sym, pure);
|
||||
}
|
||||
|
||||
|
@ -74,26 +74,26 @@ public class PSystemDonors extends AbstractPSystem {
|
||||
private static final int COLS = 6;
|
||||
private static final int FREE_LINES = 6;
|
||||
|
||||
public static final String DONORS = "6vaB02mFUBXRGOc9nbfsvvsjZ9-86KqYM9ud58U1HJpT3OW_mBtJutuZ_KLqfNlVD2FQiZN5USOGiI3e"
|
||||
+ "yJIvPjZctXu8Sw9y2FxT21uW0qH9r4QrBFUas6sRAaDAyEyxN_abw1tUiK6YkKgZnP5xPFSBxs-6ytpJ"
|
||||
+ "-EYbPy0IgdwAxcl_Tqqhw_AcAWpfifenC-hqX2hcrgWHaIB-_rJhRgSsJgOw3IG1dSgvWflgLC2h4nu3"
|
||||
+ "YpI3MyPvDMaoAYQ-YPHWQvGGD3epjEMazZco8OF4B_K3jDbSOQd8cL0SeoJHzVNSlcq3pI-NU15y8HPi"
|
||||
+ "7fX3AOThWHBdHeo4JmGDBRFeZQqwikI97OPIQ64V_j18ZdYaCdCwMYJy7e62eATnGD8BjMd2sT75W2eZ"
|
||||
+ "sQBFabHT6G_XpkkmFCLge-5EiF2pu2oWXY3_Woxuz5ZrqUGSLqCjgQT9tggjH_rAl9Us6T4t_MYIA9_j"
|
||||
+ "JREYk0kKBLAThJx7UCqZ87TBhRpYowWZcoEuzzsx6jO_MY0_0jrM4vNapx8lB2GXhgtiWtIT6wyyUX6E"
|
||||
+ "sP1fOXs_YosliHUwmfMDoR82BFHf-xhIX0osq9NBmz0JMfLfrlb4IrfQlr_qwB9ndt1DfTczW_G-okOY"
|
||||
+ "_x_RlSmCnG4wLc8MT9sWQ5nDgzvY0n6S5hemv2OWLw2ykMx5pUiYl-e3WhUG4OZ2XgGTulMHSjT5YEbO"
|
||||
+ "rKqfHW3pfvHpaGXO4A5Mkw1RKIKJAUlT7gUhP_goCNUVzC5rky4OnJ6Tr5Y4xzu5zp2iL8rcjbaxXJa5"
|
||||
+ "B-Drd5VTQwHVnRAzXVUK3wdvHmRYJE-CY9GVqTYsye_2tJeAivXBRjRbkxeV73nqvu8pMBIC6MssGvQ0"
|
||||
+ "mjbadAbV6NvQClmTWMp2xurDNa7eJbWFOMOqWjjRasjgSec4ptIMusONW6ArUCMkY719eMgMcSeMDiNa"
|
||||
+ "6Qj78KD-ntm2I-LQUDgmrjoLUKRrAAZ3UNUiMjQlGytR0ghBOOACj51gf9eYVIsGWMjrUfPQ1zkV5bZG"
|
||||
+ "j_6eYbM7ujicsgxSe68AJ1SHVj4W4cb1hKGlEKaCy3z_VgKUxUlWupkZV38EaZqaCL05hKu_SMeQF8zX"
|
||||
+ "PQpNwFlrrdQluC-_rz4cf_PuvgS8ekSW6lys2k0e9p62fu6_BXybxoHODJgrKPGhroYz4KXOi1FlpA8U"
|
||||
+ "6MRKxyHakHcvw1NRXwhyxUGAN2o6sB3Y8fEc6B7afBVTUb15RD_vnk8WXuQ_YoeJChdAPJKmGY6sGYzE"
|
||||
+ "Ukmsod2NLGlme3ek4vZxrM-dMTuqvhnZgMvu3CWtH-HKqIEqiAQcjMCXi56C-Rsb_LIcntyoebz4QtRi"
|
||||
+ "rKFlGVaziWiqV5k3z3D6Wk4YPST0kxdFoGZSVCCXRqpDYKmNYwrSTCMmymOhx3Vs4bb8U65Rgrp2N7ju"
|
||||
+ "pUcNTtbMsv6ZRI7xM3MQNYYgY178XSKwNPrOAELu84LIC6TlcIWYxQ0tkAHd04vHSBo_sn2E5PeVqQnz"
|
||||
+ "FADHp6MTUt4FOYgSt4zxKhQRdfK7";
|
||||
public static final String DONORS = "6ySB02mFUBXRGOc9nbfsvvsjZ8zbDKqYM9ud58U1HJpT3OW_mBtJutuZ_KLqfNlVD2FQiZN5USOGiI3e"
|
||||
+ "yJIvPjZctXvupCdFe-IxmsY4GPYio__BbYQxT2r0gWmfmRDSR_uPnVYUEsbeodQv4793qY-yxupDizFu"
|
||||
+ "ujMZ2Te8_1ZOL_zlwf1nUQWAmz1iXJ4O5OrGdJ_q56ijjVR_KOqBfs3VeOeUIuxfrCLrE5JHYCwA5uhL"
|
||||
+ "E0UtZFFHfCMecD0cKefgeuGYEPYXhIRLvyWL6TpyKZz0cwxjcX8v4efzbaXqV-rftt60ziibFtJoGopO"
|
||||
+ "8h20Ye_i9oXvRSIuoHT1GyjSzCPM7Ldo90E6KkZ2tloXB8wufsJcChIuAN062ehSne78I6hJ0hC3Ym5L"
|
||||
+ "Ug95doOfkZ5kmftFOLcArKR3iy2YW2Nd06ioyZ_e4pxTTtraSioRefQKfqdUozQZSTMzbsipec_wqIHH"
|
||||
+ "lhPtoTBZIb4rJ-bizUdpjRf3xfgowl4leqOyUt2tqq8Q5XyfY1-6RXiJbUJFj8M558HhA_qWNUR6AsSl"
|
||||
+ "mZ4RifIjus-nPJNsyYvViJ6nB7SMUFTytMXAXbhAAkGqTBjMPIxjVAAbD3N-B_BeqVc_m9fAita7wJrB"
|
||||
+ "vpB_lnjMQiOI3Zesn2pNpGB5ucbIzIusBaBJJAU6t0J83QZk9hVYRdKHVzG7vDvICX65pRO4YVPKSfUB"
|
||||
+ "4APZfPjAZ02MJ2dd-XjR4FcgrS7eLaI9HSeYz35CUgRjgx1D-k1ckxanYQCwfNmIVbi8tCEmKYsQsQ5j"
|
||||
+ "6tCnNiR7SLvrh_v-bRJjBRodV4ZDAnZ8AoqOOIaveZoEie-4kmOAihXBNXhYUuHr3XwwSy4PB5h6Z3RR"
|
||||
+ "8Gj3SZmPP-bN31-Q37lxNJPihurDNi3xghCJmiZ8WzTBacjgSOcRV3DOJWxR08gDnIjs-PcB25LRRYgR"
|
||||
+ "wnAcHgmUXGhu7VC9p9LjuSfZlTsru0nO5DN1l3lMM1gtAStR0ghBgOAOTA6CcT8KQNix6NfMfsUf3R3z"
|
||||
+ "gUuBpZOVLTWqABsjeks63QPFeUaKwHSD8X4IhGgvrAGmm7Tz_4eywEiGupkzR24EaHQI5A02oZaVE9K6"
|
||||
+ "ppsrbFKQ_N-jjTFA-VFlTMI3KtlSyvD2w1a8ujz3WHpX539v6lXwymVW7G6hOfPs2h1oZTppG5A3dNXd"
|
||||
+ "5dN_CADp9nRApQX5hzW-LELltww0nNA83IikOccAwLkSidPg19LVzvrlB0voMFYxg38Xawkdh3P6mcVG"
|
||||
+ "YnCT-vgbk7FD116CZai5xdxrMJFDkumvNx6iRZWuyiqH6L9q3osg9MbjFZsmKPpvlPLjIARxNp8Ydrzg"
|
||||
+ "rlVgeRTJ_Xnf0is_jTJx6LbWcCWuCB2-tEV40pVU2AWBKpl-wMB1bOkk67PvmHRs6_iHMPxmmhPMcGXp"
|
||||
+ "dswLeoyByQnsUewr9UzZez7qGQ9IU23R5-lqsOd5iWoFP84KhjbR9ej8w_I6Ixg3S8Z2-VxU1dEilFaH"
|
||||
+ "cTNcqnk5NDhSYtiG-N1ycgIcNJOxSfCRwuxSRIC1-ge0";
|
||||
|
||||
/*
|
||||
* Special thanks to our sponsors and donors:
|
||||
|
@ -269,9 +269,10 @@ public class QuoteUtils {
|
||||
"Jurarire V srry gur arrq gb rkrepvfr, V yvr qbja hagvy vg tbrf njnl", "Ernyvgl pbagvahrf gb ehva zl yvsr",
|
||||
"Vs lbh gvpxyr hf, qb jr abg ynhtu?", "V xabj n HQC wbxr, ohg lbh zvtug abg trg vg",
|
||||
"Chvfdhr prf zlfgrerf abhf qrcnffrag, srvtabaf q'ra rger y'betnavfngrhe.",
|
||||
"V qba'g gnxr nal erfcbafvovyvgl ng nyy",
|
||||
"V qba'g gnxr erfcbafvovyvgl ng nyy",
|
||||
"Gurer'f n jbeq sbe crbcyr jub guvax rirelbar vf pbafcvevat ntnvafg gurz: creprcgvir",
|
||||
"V'yy yrg gung cnff orpnhfr guvf vf tbbqolr");
|
||||
"V'yy yrg gung cnff orpnhfr guvf vf tbbqolr", "V ybir vg jura n cyna pbzrf gbtrgure",
|
||||
"Znxr hf nyy fnsr. Tb onpx gb lbhe ohaxre");
|
||||
|
||||
private QuoteUtils() {
|
||||
}
|
||||
|
@ -58,24 +58,24 @@ public abstract class USymbol {
|
||||
public final static USymbol FRAME = record("FRAME", SkinParameter.FRAME, new USymbolFrame());
|
||||
public final static USymbol NODE = record("NODE", SkinParameter.NODE, new USymbolNode());
|
||||
public final static USymbol ARTIFACT = record("ARTIFACT", SkinParameter.ARTIFACT, new USymbolArtifact());
|
||||
public final static USymbol PACKAGE = record("PACKAGE", SkinParameter.PACKAGE, new USymbolFolder(
|
||||
SkinParameter.PACKAGE, true));
|
||||
public final static USymbol FOLDER = record("FOLDER", SkinParameter.FOLDER, new USymbolFolder(SkinParameter.FOLDER,
|
||||
false));
|
||||
public final static USymbol PACKAGE = record("PACKAGE", SkinParameter.PACKAGE,
|
||||
new USymbolFolder(SkinParameter.PACKAGE, true));
|
||||
public final static USymbol FOLDER = record("FOLDER", SkinParameter.FOLDER,
|
||||
new USymbolFolder(SkinParameter.FOLDER, false));
|
||||
public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile());
|
||||
public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect(
|
||||
SkinParameter.RECTANGLE));
|
||||
public final static USymbol LABEL = record("LABEL", SkinParameter.RECTANGLE, new USymbolLabel(
|
||||
SkinParameter.RECTANGLE));
|
||||
public final static USymbol ARCHIMATE = record("ARCHIMATE", SkinParameter.ARCHIMATE, new USymbolRect(
|
||||
SkinParameter.ARCHIMATE));
|
||||
public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS, new USymbolCollections(
|
||||
SkinParameter.RECTANGLE));
|
||||
public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE,
|
||||
new USymbolRect(SkinParameter.RECTANGLE));
|
||||
public final static USymbol LABEL = record("LABEL", SkinParameter.RECTANGLE,
|
||||
new USymbolLabel(SkinParameter.RECTANGLE));
|
||||
public final static USymbol ARCHIMATE = record("ARCHIMATE", SkinParameter.ARCHIMATE,
|
||||
new USymbolRect(SkinParameter.ARCHIMATE));
|
||||
public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS,
|
||||
new USymbolCollections(SkinParameter.RECTANGLE));
|
||||
public final static USymbol AGENT = record("AGENT", SkinParameter.AGENT, new USymbolRect(SkinParameter.AGENT));
|
||||
public final static USymbol ACTOR_STICKMAN = record("ACTOR_STICKMAN", SkinParameter.ACTOR, new USymbolActor(
|
||||
ActorStyle.STICKMAN));
|
||||
public final static USymbol ACTOR_AWESOME = record("ACTOR_AWESOME", SkinParameter.ACTOR, new USymbolActor(
|
||||
ActorStyle.AWESOME));
|
||||
public final static USymbol ACTOR_STICKMAN = record("ACTOR_STICKMAN", SkinParameter.ACTOR,
|
||||
new USymbolActor(ActorStyle.STICKMAN));
|
||||
public final static USymbol ACTOR_AWESOME = record("ACTOR_AWESOME", SkinParameter.ACTOR,
|
||||
new USymbolActor(ActorStyle.AWESOME));
|
||||
public final static USymbol USECASE = null;
|
||||
public final static USymbol COMPONENT1 = record("COMPONENT1", SkinParameter.COMPONENT1, new USymbolComponent1());
|
||||
public final static USymbol COMPONENT2 = record("COMPONENT2", SkinParameter.COMPONENT2, new USymbolComponent2());
|
||||
@ -235,7 +235,7 @@ public abstract class USymbol {
|
||||
} else if (symbol.equalsIgnoreCase("actor")) {
|
||||
usymbol = skinParam.getActorStyle().getUSymbol();
|
||||
} else if (symbol.equalsIgnoreCase("component")) {
|
||||
usymbol = skinParam.useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1;
|
||||
usymbol = skinParam.componentStyle().toSymbol();
|
||||
} else if (symbol.equalsIgnoreCase("boundary")) {
|
||||
usymbol = USymbol.BOUNDARY;
|
||||
} else if (symbol.equalsIgnoreCase("control")) {
|
||||
|
@ -119,11 +119,11 @@ public class LatexBuilder implements ScientificEquation {
|
||||
}
|
||||
|
||||
public MutableImage muteColor(Color newColor) {
|
||||
throw new UnsupportedOperationException();
|
||||
return this;
|
||||
}
|
||||
|
||||
public MutableImage muteTransparentColor(Color newColor) {
|
||||
throw new UnsupportedOperationException();
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,27 +46,50 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
|
||||
|
||||
public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements ComplementPattern {
|
||||
|
||||
public IRegex toRegex(String suffix) {
|
||||
return new RegexLeaf("COMPLEMENT" + suffix,
|
||||
"(?:at|with|after|(\\d+)[%s]+days?[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)");
|
||||
private static final int POS_NB1 = 0;
|
||||
private static final int POS_DAY_OR_WEEK1 = 1;
|
||||
private static final int POS_NB2 = 2;
|
||||
private static final int POS_DAY_OR_WEEK2 = 3;
|
||||
private static final int POS_BEFORE_OR_AFTER = 4;
|
||||
private static final int POS_CODE_OTHER = 5;
|
||||
private static final int POS_START_OR_END = 6;
|
||||
|
||||
public IRegex toRegex(String suffix) { // "+"
|
||||
return new RegexLeaf("COMPLEMENT" + suffix, "(?:at|with|after|" + //
|
||||
"(\\d+)[%s]+(day|week)s?" + //
|
||||
"(?:[%s]+and[%s]+(\\d+)[%s]+(day|week)s?)?" + //
|
||||
"[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)");
|
||||
}
|
||||
|
||||
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
|
||||
final String code = arg.get("COMPLEMENT" + suffix, 2);
|
||||
final String position = arg.get("COMPLEMENT" + suffix, 3);
|
||||
final String code = arg.get("COMPLEMENT" + suffix, POS_CODE_OTHER);
|
||||
final String startOrEnd = arg.get("COMPLEMENT" + suffix, POS_START_OR_END);
|
||||
final Moment task = system.getExistingMoment(code);
|
||||
if (task == null) {
|
||||
return Failable.<Complement> error("No such task " + code);
|
||||
return Failable.<Complement>error("No such task " + code);
|
||||
}
|
||||
final String days = arg.get("COMPLEMENT" + suffix, 0);
|
||||
TaskInstant result = new TaskInstant(task, TaskAttribute.fromString(position));
|
||||
if (days != null) {
|
||||
int delta = Integer.parseInt(days);
|
||||
if ("before".equalsIgnoreCase(arg.get("COMPLEMENT" + suffix, 1))) {
|
||||
TaskInstant result = new TaskInstant(task, TaskAttribute.fromString(startOrEnd));
|
||||
final String nb1 = arg.get("COMPLEMENT" + suffix, POS_NB1);
|
||||
if (nb1 != null) {
|
||||
final int factor1 = arg.get("COMPLEMENT" + suffix, POS_DAY_OR_WEEK1).startsWith("w") ? system.daysInWeek()
|
||||
: 1;
|
||||
final int days1 = Integer.parseInt(nb1) * factor1;
|
||||
|
||||
final String nb2 = arg.get("COMPLEMENT" + suffix, POS_NB2);
|
||||
int days2 = 0;
|
||||
if (nb2 != null) {
|
||||
final int factor2 = arg.get("COMPLEMENT" + suffix, POS_DAY_OR_WEEK2).startsWith("w")
|
||||
? system.daysInWeek()
|
||||
: 1;
|
||||
days2 = Integer.parseInt(nb2) * factor2;
|
||||
}
|
||||
|
||||
int delta = days1 + days2;
|
||||
if ("before".equalsIgnoreCase(arg.get("COMPLEMENT" + suffix, POS_BEFORE_OR_AFTER))) {
|
||||
delta = -delta;
|
||||
}
|
||||
result = result.withDelta(delta);
|
||||
}
|
||||
return Failable.<Complement> ok(result);
|
||||
return Failable.<Complement>ok(result);
|
||||
}
|
||||
}
|
||||
|
@ -47,15 +47,24 @@ public class ComplementSeveralDays implements ComplementPattern {
|
||||
|
||||
public IRegex toRegex(String suffix) {
|
||||
return new RegexConcat( //
|
||||
new RegexLeaf("COMPLEMENT" + suffix, "(\\d+)[%s]+(days?|weeks?)")); //
|
||||
new RegexLeaf("COMPLEMENT" + suffix, "(\\d+)[%s]+(day|week)s?" + //
|
||||
"(?:[%s]+and[%s]+(\\d+)[%s]+(day|week)s?)?" //
|
||||
)); //
|
||||
}
|
||||
|
||||
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
|
||||
final String number = arg.get("COMPLEMENT" + suffix, 0);
|
||||
final boolean inWeeks = arg.get("COMPLEMENT" + suffix, 1).startsWith("w");
|
||||
final int factor = inWeeks ? system.daysInWeek() : 1;
|
||||
final int days = Integer.parseInt(number) * factor;
|
||||
return Failable.<Complement> ok(Load.inWinks(days));
|
||||
final String nb1 = arg.get("COMPLEMENT" + suffix, 0);
|
||||
final int factor1 = arg.get("COMPLEMENT" + suffix, 1).startsWith("w") ? system.daysInWeek() : 1;
|
||||
final int days1 = Integer.parseInt(nb1) * factor1;
|
||||
|
||||
final String nb2 = arg.get("COMPLEMENT" + suffix, 2);
|
||||
int days2 = 0;
|
||||
if (nb2 != null) {
|
||||
final int factor2 = arg.get("COMPLEMENT" + suffix, 3).startsWith("w") ? system.daysInWeek() : 1;
|
||||
days2 = Integer.parseInt(nb2) * factor2;
|
||||
}
|
||||
|
||||
return Failable.<Complement>ok(Load.inWinks(days1 + days2));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -245,17 +245,17 @@ public class SFile implements Comparable<SFile> {
|
||||
// In SANDBOX, we cannot read any files
|
||||
return false;
|
||||
}
|
||||
// Files in "plantuml.include.path" and "plantuml.whitelist.path" are ok.
|
||||
if (isIn(SecurityUtils.getPath("plantuml.include.path"))) {
|
||||
// Files in "plantuml.include.path" and "plantuml.allowlist.path" are ok.
|
||||
if (isInAllowList(SecurityUtils.getPath("plantuml.include.path"))) {
|
||||
return true;
|
||||
}
|
||||
if (isIn(SecurityUtils.getPath("plantuml.whitelist.path"))) {
|
||||
if (isInAllowList(SecurityUtils.getPath("plantuml.allowlist.path"))) {
|
||||
return true;
|
||||
}
|
||||
if (SecurityUtils.getSecurityProfile() == SecurityProfile.INTERNET) {
|
||||
return false;
|
||||
}
|
||||
if (SecurityUtils.getSecurityProfile() == SecurityProfile.WHITELIST) {
|
||||
if (SecurityUtils.getSecurityProfile() == SecurityProfile.ALLOWLIST) {
|
||||
return false;
|
||||
}
|
||||
if (SecurityUtils.getSecurityProfile() != SecurityProfile.UNSECURE) {
|
||||
@ -272,11 +272,11 @@ public class SFile implements Comparable<SFile> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isIn(List<SFile> whiteList) {
|
||||
private boolean isInAllowList(List<SFile> allowlist) {
|
||||
final String path = getCleanPathSecure();
|
||||
for (SFile white : whiteList) {
|
||||
if (path.startsWith(white.getCleanPathSecure())) {
|
||||
// File directory is in the whiteList
|
||||
for (SFile allow : allowlist) {
|
||||
if (path.startsWith(allow.getCleanPathSecure())) {
|
||||
// File directory is in the allowlist
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,8 @@
|
||||
package net.sourceforge.plantuml.security;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@ -110,10 +111,13 @@ public class SURL {
|
||||
// We are UNSECURE anyway
|
||||
return true;
|
||||
}
|
||||
if (isInWhiteList()) {
|
||||
if (isInAllowList()) {
|
||||
return true;
|
||||
}
|
||||
if (SecurityUtils.getSecurityProfile() == SecurityProfile.INTERNET) {
|
||||
if (pureIP(cleanPath(internal.toString()))) {
|
||||
return false;
|
||||
}
|
||||
final int port = internal.getPort();
|
||||
// Using INTERNET profile, port 80 and 443 are ok
|
||||
if (port == 80 || port == 443) {
|
||||
@ -123,10 +127,17 @@ public class SURL {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInWhiteList() {
|
||||
private boolean pureIP(String full) {
|
||||
if (full.matches("^https?://\\d+\\.\\d+\\.\\d+\\.\\d+\\/")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isInAllowList() {
|
||||
final String full = cleanPath(internal.toString());
|
||||
for (String white : getWhiteList()) {
|
||||
if (full.startsWith(cleanPath(white))) {
|
||||
for (String allow : getAllowList()) {
|
||||
if (full.startsWith(cleanPath(allow))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -141,31 +152,51 @@ public class SURL {
|
||||
return path;
|
||||
}
|
||||
|
||||
private List<String> getWhiteList() {
|
||||
final String env = SecurityUtils.getenv("plantuml.whitelist.url");
|
||||
private List<String> getAllowList() {
|
||||
final String env = SecurityUtils.getenv("plantuml.allowlist.url");
|
||||
if (env == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(env).split(";"));
|
||||
}
|
||||
|
||||
public URLConnection openConnection() {
|
||||
// Added by Alain Corbiere
|
||||
public byte[] getBytes() {
|
||||
if (isUrlOk())
|
||||
try {
|
||||
return internal.openConnection();
|
||||
} catch (IOException e) {
|
||||
InputStream input = null;
|
||||
try {
|
||||
final URLConnection connection = internal.openConnection();
|
||||
if (connection == null) {
|
||||
return null;
|
||||
}
|
||||
input = connection.getInputStream();
|
||||
final ByteArrayOutputStream image = new ByteArrayOutputStream();
|
||||
final byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
while ((read = input.read(buffer)) > 0) {
|
||||
image.write(buffer, 0, read);
|
||||
}
|
||||
image.close();
|
||||
return image.toByteArray();
|
||||
} finally {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream openStream() {
|
||||
if (isUrlOk())
|
||||
try {
|
||||
return internal.openStream();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if (isUrlOk()) {
|
||||
final byte data[] = getBytes();
|
||||
if (data != null) {
|
||||
return new ByteArrayInputStream(data);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public enum SecurityProfile {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
WHITELIST,
|
||||
ALLOWLIST,
|
||||
|
||||
/**
|
||||
* This mode is designed for PlantUML running in a web server.
|
||||
@ -108,8 +108,8 @@ public enum SecurityProfile {
|
||||
final String env = SecurityUtils.getenv("PLANTUML_SECURITY_PROFILE");
|
||||
if ("SANDBOX".equalsIgnoreCase(env)) {
|
||||
return SANDBOX;
|
||||
} else if ("WHITELIST".equalsIgnoreCase(env)) {
|
||||
return WHITELIST;
|
||||
} else if ("ALLOWLIST".equalsIgnoreCase(env)) {
|
||||
return ALLOWLIST;
|
||||
} else if ("INTERNET".equalsIgnoreCase(env)) {
|
||||
return INTERNET;
|
||||
} else if ("UNSECURE".equalsIgnoreCase(env)) {
|
||||
@ -125,7 +125,7 @@ public enum SecurityProfile {
|
||||
switch (this) {
|
||||
case SANDBOX:
|
||||
return "This is completely safe: no access to local files or to distant URL.";
|
||||
case WHITELIST:
|
||||
case ALLOWLIST:
|
||||
return "Some local ressource may be accessible.";
|
||||
case INTERNET:
|
||||
return "<i>Mode designed for server connected to Internet.";
|
||||
|
@ -66,7 +66,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorSet;
|
||||
|
||||
public class CommandArrow extends SingleLineCommand2<SequenceDiagram> {
|
||||
|
||||
private static final String ANCHOR = "(\\{([\\p{L}0-9_]+)\\}[%s]+)?";
|
||||
static final String ANCHOR = "(\\{([\\p{L}0-9_]+)\\}[%s]+)?";
|
||||
|
||||
public CommandArrow() {
|
||||
super(getRegexConcat());
|
||||
@ -77,44 +77,42 @@ public class CommandArrow extends SingleLineCommand2<SequenceDiagram> {
|
||||
}
|
||||
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat
|
||||
.build(CommandArrow.class.getName(),
|
||||
RegexLeaf.start(), //
|
||||
new RegexLeaf("PARALLEL", "(&[%s]*)?"), //
|
||||
new RegexLeaf("ANCHOR", ANCHOR), //
|
||||
new RegexOr("PART1", //
|
||||
new RegexLeaf("PART1CODE", "([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART1LONG", "[%g]([^%g]+)[%g]"), //
|
||||
new RegexLeaf("PART1LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART1CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), //
|
||||
new RegexLeaf("PART1ANCHOR", ANCHOR), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("ARROW_DRESSING1",
|
||||
"([%s][ox]|(?:[%s][ox])?<<?|(?:[%s][ox])?//?|(?:[%s][ox])?\\\\\\\\?)?"), //
|
||||
new RegexOr(new RegexConcat( //
|
||||
new RegexLeaf("ARROW_BODYA1", "(-+)"), //
|
||||
new RegexLeaf("ARROW_STYLE1", getColorOrStylePattern()), //
|
||||
new RegexLeaf("ARROW_BODYB1", "(-*)")), //
|
||||
new RegexConcat( //
|
||||
new RegexLeaf("ARROW_BODYA2", "(-*)"), //
|
||||
new RegexLeaf("ARROW_STYLE2", getColorOrStylePattern()), //
|
||||
new RegexLeaf("ARROW_BODYB2", "(-+)"))), //
|
||||
new RegexLeaf("ARROW_DRESSING2",
|
||||
"(>>?(?:[ox][%s])?|//?(?:[ox][%s])?|\\\\\\\\?(?:[ox][%s])?|[ox][%s])?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexOr("PART2", //
|
||||
new RegexLeaf("PART2CODE", "([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART2LONG", "[%g]([^%g]+)[%g]"), //
|
||||
new RegexLeaf("PART2LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART2CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), //
|
||||
new RegexLeaf("PART2ANCHOR", ANCHOR), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), RegexLeaf.end());
|
||||
return RegexConcat.build(CommandArrow.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("PARALLEL", "(&[%s]*)?"), //
|
||||
new RegexLeaf("ANCHOR", ANCHOR), //
|
||||
new RegexOr("PART1", //
|
||||
new RegexLeaf("PART1CODE", "([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART1LONG", "[%g]([^%g]+)[%g]"), //
|
||||
new RegexLeaf("PART1LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART1CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), //
|
||||
new RegexLeaf("PART1ANCHOR", ANCHOR), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("ARROW_DRESSING1",
|
||||
"([%s][ox]|(?:[%s][ox])?<<?|(?:[%s][ox])?//?|(?:[%s][ox])?\\\\\\\\?)?"), //
|
||||
new RegexOr(new RegexConcat( //
|
||||
new RegexLeaf("ARROW_BODYA1", "(-+)"), //
|
||||
new RegexLeaf("ARROW_STYLE1", getColorOrStylePattern()), //
|
||||
new RegexLeaf("ARROW_BODYB1", "(-*)")), //
|
||||
new RegexConcat( //
|
||||
new RegexLeaf("ARROW_BODYA2", "(-*)"), //
|
||||
new RegexLeaf("ARROW_STYLE2", getColorOrStylePattern()), //
|
||||
new RegexLeaf("ARROW_BODYB2", "(-+)"))), //
|
||||
new RegexLeaf("ARROW_DRESSING2",
|
||||
"(>>?(?:[ox][%s])?|//?(?:[ox][%s])?|\\\\\\\\?(?:[ox][%s])?|[ox][%s])?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexOr("PART2", //
|
||||
new RegexLeaf("PART2CODE", "([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART2LONG", "[%g]([^%g]+)[%g]"), //
|
||||
new RegexLeaf("PART2LONGCODE", "[%g]([^%g]+)[%g][%s]*as[%s]+([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("PART2CODELONG", "([\\p{L}0-9_.@]+)[%s]+as[%s]*[%g]([^%g]+)[%g]")), //
|
||||
new RegexLeaf("PART2ANCHOR", ANCHOR), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
|
||||
RegexLeaf.spaceZeroOrMore(), new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), RegexLeaf.end());
|
||||
}
|
||||
|
||||
private Participant getOrCreateParticipant(SequenceDiagram system, RegexResult arg2, String n) {
|
||||
|
@ -142,6 +142,9 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
|
||||
if (parallel) {
|
||||
msg.goParallel();
|
||||
}
|
||||
msg.setAnchor(arg.get("ANCHOR", 1));
|
||||
msg.setPart1Anchor(arg.get("PART1ANCHOR", 1));
|
||||
msg.setPart2Anchor(arg.get("PART2ANCHOR", 1));
|
||||
|
||||
final String error = diagram.addMessage(msg);
|
||||
if (error != null) {
|
||||
|
@ -53,6 +53,7 @@ public class CommandExoArrowLeft extends CommandExoArrowAny {
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandExoArrowLeft.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("PARALLEL", "(&[%s]*)?"), //
|
||||
new RegexLeaf("ANCHOR", CommandArrow.ANCHOR), //
|
||||
new RegexLeaf("SHORT", "([?\\[\\]][ox]?)?"), //
|
||||
new RegexOr( //
|
||||
new RegexConcat( //
|
||||
|
@ -53,6 +53,7 @@ public class CommandExoArrowRight extends CommandExoArrowAny {
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandExoArrowRight.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("PARALLEL", "(&[%s]*)?"), //
|
||||
new RegexLeaf("ANCHOR", CommandArrow.ANCHOR), //
|
||||
new RegexLeaf("PARTICIPANT", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
new RegexLeaf("ARROW_SUPPCIRCLE", "([%s]+[ox])?"), //
|
||||
|
@ -144,7 +144,7 @@ public class StyleLoader {
|
||||
if (mPropertyAndValue.find()) {
|
||||
final PName key = PName.getFromName(mPropertyAndValue.group(1));
|
||||
final String value = mPropertyAndValue.group(2);
|
||||
if (key != null) {
|
||||
if (key != null && maps.size() > 0) {
|
||||
maps.get(maps.size() - 1).put(key, new ValueImpl(value, counter));
|
||||
}
|
||||
continue;
|
||||
|
@ -54,7 +54,6 @@ import net.sourceforge.plantuml.ColorParam;
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.FontParam;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.LineParam;
|
||||
import net.sourceforge.plantuml.SkinParam;
|
||||
import net.sourceforge.plantuml.SkinParamUtils;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
@ -305,7 +304,7 @@ public class Cluster implements Moveable {
|
||||
return StyleSignature.of(SName.root, SName.element, styleName, SName.group);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug, UStroke stroke, UmlDiagramType umlDiagramType, ISkinParam skinParam2) {
|
||||
public void drawU(UGraphic ug, UStroke strokeForState, UmlDiagramType umlDiagramType, ISkinParam skinParam2) {
|
||||
if (group.isHidden()) {
|
||||
return;
|
||||
}
|
||||
@ -345,12 +344,12 @@ public class Cluster implements Moveable {
|
||||
final boolean isState = umlDiagramType == UmlDiagramType.STATE;
|
||||
if (isState) {
|
||||
if (group.getColors(skinParam).getSpecificLineStroke() != null) {
|
||||
stroke = group.getColors(skinParam).getSpecificLineStroke();
|
||||
strokeForState = group.getColors(skinParam).getSpecificLineStroke();
|
||||
}
|
||||
if (group.getColors(skinParam).getColor(ColorType.LINE) != null) {
|
||||
borderColor = group.getColors(skinParam).getColor(ColorType.LINE);
|
||||
}
|
||||
drawUState(ug, borderColor, skinParam2, stroke, umlDiagramType);
|
||||
drawUState(ug, borderColor, skinParam2, strokeForState, umlDiagramType);
|
||||
return;
|
||||
}
|
||||
PackageStyle packageStyle = group.getPackageStyle();
|
||||
@ -365,10 +364,12 @@ public class Cluster implements Moveable {
|
||||
}
|
||||
|
||||
final double shadowing;
|
||||
final UStroke stroke;
|
||||
if (SkinParam.USE_STYLES()) {
|
||||
final Style style = getDefaultStyleDefinition(umlDiagramType.getStyleName())
|
||||
.getMergedStyle(skinParam.getCurrentStyleBuilder());
|
||||
shadowing = style.value(PName.Shadowing).asDouble();
|
||||
stroke = style.getStroke();
|
||||
} else {
|
||||
if (group.getUSymbol() == null) {
|
||||
shadowing = skinParam2.shadowing2(group.getStereotype(), USymbol.PACKAGE.getSkinParameter()) ? 3
|
||||
@ -377,6 +378,7 @@ public class Cluster implements Moveable {
|
||||
shadowing = skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3
|
||||
: 0;
|
||||
}
|
||||
stroke = getStrokeInternal(skinParam2);
|
||||
}
|
||||
HColor backColor = getBackColor(umlDiagramType);
|
||||
backColor = getBackColor(backColor, skinParam2, group.getStereotype(), umlDiagramType.getStyleName());
|
||||
@ -384,9 +386,8 @@ public class Cluster implements Moveable {
|
||||
final double roundCorner = group.getUSymbol() == null ? 0
|
||||
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, stereotype);
|
||||
|
||||
final UStroke stroke2 = getStrokeInternal(skinParam2);
|
||||
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
|
||||
zstereo, minX, minY, maxX, maxY, stroke2);
|
||||
zstereo, minX, minY, maxX, maxY, stroke);
|
||||
decoration.drawU(ug, backColor, borderColor, shadowing, roundCorner,
|
||||
skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false),
|
||||
skinParam2.getStereotypeAlignment());
|
||||
@ -410,14 +411,15 @@ public class Cluster implements Moveable {
|
||||
if (colors.getSpecificLineStroke() != null) {
|
||||
return colors.getSpecificLineStroke();
|
||||
}
|
||||
if (group.getUSymbol() != null) {
|
||||
if (group.getUSymbol() != null && group.getUSymbol() != USymbol.PACKAGE) {
|
||||
return group.getUSymbol().getSkinParameter().getStroke(skinParam, group.getStereotype());
|
||||
}
|
||||
UStroke stroke = skinParam.getThickness(LineParam.packageBorder, group.getStereotype());
|
||||
if (stroke == null) {
|
||||
stroke = new UStroke(1.5);
|
||||
}
|
||||
return stroke;
|
||||
return GeneralImageBuilder.getForcedStroke(group.getStereotype(), skinParam);
|
||||
// UStroke stroke = skinParam.getThickness(LineParam.packageBorder, group.getStereotype());
|
||||
// if (stroke == null) {
|
||||
// stroke = new UStroke(1.5);
|
||||
// }
|
||||
// return stroke;
|
||||
}
|
||||
|
||||
public void manageEntryExitPoint(StringBounder stringBounder) {
|
||||
|
@ -54,6 +54,7 @@ import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.FontParam;
|
||||
import net.sourceforge.plantuml.Guillemet;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.LineParam;
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.OptionFlags;
|
||||
import net.sourceforge.plantuml.Pragma;
|
||||
@ -134,6 +135,7 @@ import net.sourceforge.plantuml.svek.image.EntityImageTips;
|
||||
import net.sourceforge.plantuml.svek.image.EntityImageUseCase;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
public final class GeneralImageBuilder {
|
||||
@ -200,7 +202,8 @@ public final class GeneralImageBuilder {
|
||||
return new EntityImageLollipopInterface(leaf, skinParam);
|
||||
}
|
||||
if (leaf.getLeafType() == LeafType.CIRCLE) {
|
||||
return new EntityImageDescription(leaf, skinParam, portionShower, links, umlDiagramType.getStyleName());
|
||||
return new EntityImageDescription(leaf, skinParam, portionShower, links, umlDiagramType.getStyleName(),
|
||||
null);
|
||||
}
|
||||
|
||||
if (leaf.getLeafType() == LeafType.DESCRIPTION) {
|
||||
@ -209,7 +212,11 @@ public final class GeneralImageBuilder {
|
||||
} else if (OptionFlags.USE_INTERFACE_EYE2 && leaf.getUSymbol() instanceof USymbolInterface) {
|
||||
return new EntityImageLollipopInterfaceEye2(leaf, skinParam, portionShower);
|
||||
} else {
|
||||
return new EntityImageDescription(leaf, skinParam, portionShower, links, umlDiagramType.getStyleName());
|
||||
final UStroke forced = leaf.getUSymbol() == USymbol.PACKAGE
|
||||
? getForcedStroke(leaf.getStereotype(), skinParam)
|
||||
: null;
|
||||
return new EntityImageDescription(leaf, skinParam, portionShower, links, umlDiagramType.getStyleName(),
|
||||
forced);
|
||||
}
|
||||
}
|
||||
if (leaf.getLeafType() == LeafType.USECASE) {
|
||||
@ -242,7 +249,7 @@ public final class GeneralImageBuilder {
|
||||
final HColor black = SkinParamUtils.getColor(skinParam, leaf.getStereotype(),
|
||||
leaf.getUSymbol().getColorParamBorder());
|
||||
return new EntityImageDescription(leaf, new SkinParamForecolored(skinParam, black), portionShower,
|
||||
links, umlDiagramType.getStyleName());
|
||||
links, umlDiagramType.getStyleName(), getForcedStroke(leaf.getStereotype(), skinParam));
|
||||
}
|
||||
return new EntityImageEmptyPackage(leaf, skinParam, portionShower, umlDiagramType.getStyleName());
|
||||
}
|
||||
@ -283,6 +290,14 @@ public final class GeneralImageBuilder {
|
||||
throw new UnsupportedOperationException(leaf.getLeafType().toString());
|
||||
}
|
||||
|
||||
public static UStroke getForcedStroke(Stereotype stereotype, ISkinParam skinParam) {
|
||||
UStroke stroke = skinParam.getThickness(LineParam.packageBorder, stereotype);
|
||||
if (stroke == null) {
|
||||
stroke = new UStroke(1.5);
|
||||
}
|
||||
return stroke;
|
||||
}
|
||||
|
||||
private final DotData dotData;
|
||||
private final EntityFactory entityFactory;
|
||||
private final UmlSource source;
|
||||
@ -371,7 +386,7 @@ public final class GeneralImageBuilder {
|
||||
}
|
||||
return dotData.getSkinParam().getBackgroundColor(false);
|
||||
}
|
||||
|
||||
|
||||
public IEntityImage buildImage(BaseFile basefile, String dotStrings[]) {
|
||||
if (dotData.isDegeneratedWithFewEntities(0)) {
|
||||
return new EntityImageSimpleEmpty(dotData.getSkinParam().getBackgroundColor(false));
|
||||
|
@ -98,7 +98,7 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
private final boolean fixCircleLabelOverlapping;
|
||||
|
||||
public EntityImageDescription(ILeaf entity, ISkinParam skinParam, PortionShower portionShower,
|
||||
Collection<Link> links, SName styleName) {
|
||||
Collection<Link> links, SName styleName, UStroke forceStroke) {
|
||||
super(entity, entity.getColors(skinParam).mute(skinParam));
|
||||
this.useRankSame = skinParam.useRankSame();
|
||||
this.fixCircleLabelOverlapping = skinParam.fixCircleLabelOverlapping();
|
||||
@ -133,6 +133,8 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
final HColor forecolor;
|
||||
final double roundCorner;
|
||||
final double diagonalCorner;
|
||||
final double deltaShadow;
|
||||
final UStroke stroke;
|
||||
if (SkinParam.USE_STYLES()) {
|
||||
final Style style = StyleSignature
|
||||
.of(SName.root, SName.element, styleName, symbol.getSkinParameter().getStyleName())
|
||||
@ -143,6 +145,8 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
}
|
||||
roundCorner = style.value(PName.RoundCorner).asDouble();
|
||||
diagonalCorner = style.value(PName.DiagonalCorner).asDouble();
|
||||
deltaShadow = style.value(PName.Shadowing).asDouble();
|
||||
stroke = style.getStroke();
|
||||
} else {
|
||||
forecolor = SkinParamUtils.getColor(getSkinParam(), stereotype, symbol.getColorParamBorder());
|
||||
if (backcolor == null) {
|
||||
@ -150,13 +154,17 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
}
|
||||
roundCorner = symbol.getSkinParameter().getRoundCorner(getSkinParam(), stereotype);
|
||||
diagonalCorner = symbol.getSkinParameter().getDiagonalCorner(getSkinParam(), stereotype);
|
||||
deltaShadow = getSkinParam().shadowing2(getEntity().getStereotype(), symbol.getSkinParameter()) ? 3 : 0;
|
||||
if (forceStroke == null) {
|
||||
stroke = colors.muteStroke(symbol.getSkinParameter().getStroke(getSkinParam(), stereotype));
|
||||
} else {
|
||||
stroke = forceStroke;
|
||||
}
|
||||
}
|
||||
|
||||
assert getStereo() == stereotype;
|
||||
final UStroke stroke = colors.muteStroke(symbol.getSkinParameter().getStroke(getSkinParam(), stereotype));
|
||||
|
||||
final SymbolContext ctx = new SymbolContext(backcolor, forecolor).withStroke(stroke)
|
||||
.withShadow(getSkinParam().shadowing2(getEntity().getStereotype(), symbol.getSkinParameter()) ? 3 : 0)
|
||||
final SymbolContext ctx = new SymbolContext(backcolor, forecolor).withStroke(stroke).withShadow(deltaShadow)
|
||||
.withCorner(roundCorner, diagonalCorner);
|
||||
|
||||
stereo = TextBlockUtils.empty(0, 0);
|
||||
@ -183,8 +191,7 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
}
|
||||
|
||||
private USymbol getUSymbol(ILeaf entity) {
|
||||
final USymbol result = entity.getUSymbol() == null
|
||||
? (getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1)
|
||||
final USymbol result = entity.getUSymbol() == null ? getSkinParam().componentStyle().toSymbol()
|
||||
: entity.getUSymbol();
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -43,7 +43,6 @@ import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.FontParam;
|
||||
import net.sourceforge.plantuml.Guillemet;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.LineParam;
|
||||
import net.sourceforge.plantuml.SkinParamUtils;
|
||||
import net.sourceforge.plantuml.Url;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
@ -61,6 +60,7 @@ import net.sourceforge.plantuml.style.SName;
|
||||
import net.sourceforge.plantuml.svek.AbstractEntityImage;
|
||||
import net.sourceforge.plantuml.svek.Cluster;
|
||||
import net.sourceforge.plantuml.svek.ClusterDecoration;
|
||||
import net.sourceforge.plantuml.svek.GeneralImageBuilder;
|
||||
import net.sourceforge.plantuml.svek.ShapeType;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
@ -106,14 +106,6 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
|
||||
return Dimension2DDouble.delta(dim, MARGIN * 2, MARGIN * 2);
|
||||
}
|
||||
|
||||
private UStroke getStroke() {
|
||||
UStroke stroke = getSkinParam().getThickness(LineParam.packageBorder, getStereo());
|
||||
if (stroke == null) {
|
||||
stroke = new UStroke(1.5);
|
||||
}
|
||||
return stroke;
|
||||
}
|
||||
|
||||
final public void drawU(UGraphic ug) {
|
||||
if (url != null) {
|
||||
ug.startUrl(url);
|
||||
@ -128,8 +120,9 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
|
||||
final HColor back = Cluster.getBackColor(specificBackColor, skinParam, stereotype, styleName);
|
||||
final double roundCorner = 0;
|
||||
|
||||
final UStroke stroke = GeneralImageBuilder.getForcedStroke(getEntity().getStereotype(), getSkinParam());
|
||||
final ClusterDecoration decoration = new ClusterDecoration(getSkinParam().getPackageStyle(), null, desc,
|
||||
stereoBlock, 0, 0, widthTotal, heightTotal, getStroke());
|
||||
stereoBlock, 0, 0, widthTotal, heightTotal, stroke);
|
||||
|
||||
final double shadowing = getSkinParam().shadowing(getEntity().getStereotype()) ? 3 : 0;
|
||||
decoration.drawU(ug, back, SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.packageBorder),
|
||||
|
@ -76,8 +76,8 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage {
|
||||
super(entity, skinParam);
|
||||
final Stereotype stereotype = entity.getStereotype();
|
||||
|
||||
final USymbol symbol = entity.getUSymbol() == null ? (skinParam.useUml2ForComponent() ? USymbol.COMPONENT2
|
||||
: USymbol.COMPONENT1) : entity.getUSymbol();
|
||||
final USymbol symbol = entity.getUSymbol() == null ? skinParam.componentStyle().toSymbol()
|
||||
: entity.getUSymbol();
|
||||
if (symbol == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@ -93,8 +93,8 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage {
|
||||
}
|
||||
// backcolor = HtmlColorUtils.BLUE;
|
||||
final HColor forecolor = SkinParamUtils.getColor(getSkinParam(), getStereo(), symbol.getColorParamBorder());
|
||||
this.ctx = new SymbolContext(backcolor, forecolor).withStroke(new UStroke(1.5)).withShadow(
|
||||
getSkinParam().shadowing(getEntity().getStereotype()) ? 3 : 0);
|
||||
this.ctx = new SymbolContext(backcolor, forecolor).withStroke(new UStroke(1.5))
|
||||
.withShadow(getSkinParam().shadowing(getEntity().getStereotype()) ? 3 : 0);
|
||||
|
||||
if (stereotype != null && stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) != null
|
||||
&& portionShower.showPortion(EntityPortion.STEREOTYPE, entity)) {
|
||||
|
@ -180,8 +180,9 @@ public class LimitFinder extends UGraphicNo implements UGraphic {
|
||||
}
|
||||
|
||||
private void drawRectangle(double x, double y, URectangle shape) {
|
||||
addPoint(x, y);
|
||||
addPoint(x + shape.getWidth() - 1, y + shape.getHeight() - 1);
|
||||
addPoint(x - 1, y - 1);
|
||||
addPoint(x + shape.getWidth() - 1 + shape.getDeltaShadow() * 2,
|
||||
y + shape.getHeight() - 1 + shape.getDeltaShadow() * 2);
|
||||
}
|
||||
|
||||
private void drawDotPath(double x, double y, DotPath shape) {
|
||||
@ -202,7 +203,8 @@ public class LimitFinder extends UGraphicNo implements UGraphic {
|
||||
|
||||
private void drawEllipse(double x, double y, UEllipse shape) {
|
||||
addPoint(x, y);
|
||||
addPoint(x + shape.getWidth() - 1, y + shape.getHeight() - 1);
|
||||
addPoint(x + shape.getWidth() - 1 + shape.getDeltaShadow() * 2,
|
||||
y + shape.getHeight() - 1 + shape.getDeltaShadow() * 2);
|
||||
}
|
||||
|
||||
private void drawText(double x, double y, UText text) {
|
||||
|
@ -37,10 +37,8 @@ package net.sourceforge.plantuml.ugraphic.g2d;
|
||||
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
import net.sourceforge.plantuml.golem.MinMaxDouble;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UDriver;
|
||||
import net.sourceforge.plantuml.ugraphic.UParam;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
@ -65,23 +63,23 @@ public class DriverPathG2d extends DriverShadowedG2d implements UDriver<Graphics
|
||||
final UPath shape = (UPath) ushape;
|
||||
DriverLineG2d.manageStroke(param, g2d);
|
||||
|
||||
final HColor back = param.getBackcolor();
|
||||
|
||||
final ExtendedGeneralPath p = new ExtendedGeneralPath();
|
||||
final MinMaxDouble minMax = new MinMaxDouble();
|
||||
minMax.manage(x, y);
|
||||
boolean slowShadow = false;
|
||||
MinMax minMax = MinMax.getEmpty(false);
|
||||
minMax = minMax.addPoint(x, y);
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
p.moveTo(x + coord[0], y + coord[1]);
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
minMax = minMax.addPoint(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
p.lineTo(x + coord[0], y + coord[1]);
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
minMax = minMax.addPoint(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_CUBICTO) {
|
||||
p.curveTo(x + coord[0], y + coord[1], x + coord[2], y + coord[3], x + coord[4], y + coord[5]);
|
||||
minMax.manage(x + coord[4], y + coord[5]);
|
||||
slowShadow = true;
|
||||
minMax = minMax.addPoint(x + coord[4], y + coord[5]);
|
||||
} else if (type == USegmentType.SEG_ARCTO) {
|
||||
p.arcTo(coord[0], coord[1], coord[2], coord[3] != 0, coord[4] != 0, x + coord[5], y + coord[6]);
|
||||
} else {
|
||||
@ -97,32 +95,11 @@ public class DriverPathG2d extends DriverShadowedG2d implements UDriver<Graphics
|
||||
}
|
||||
|
||||
// Shadow
|
||||
final HColor back = param.getBackcolor();
|
||||
if (back != null) {
|
||||
slowShadow = true;
|
||||
}
|
||||
if (shape.getDeltaShadow() != 0 && HColorUtils.isTransparent(back) == false) {
|
||||
if (slowShadow) {
|
||||
drawShadow(g2d, p, shape.getDeltaShadow(), dpiFactor);
|
||||
if (shape.getDeltaShadow() != 0) {
|
||||
if (back == null || HColorUtils.isTransparent(back)) {
|
||||
drawOnlyLineShadowSpecial(g2d, p, shape.getDeltaShadow(), dpiFactor);
|
||||
} else {
|
||||
double lastX = 0;
|
||||
double lastY = 0;
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
// Cast float for Java 1.5
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
final Shape line = new Line2D.Double(lastX, lastY, x + coord[0], y + coord[1]);
|
||||
drawShadow(g2d, line, shape.getDeltaShadow(), dpiFactor);
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
drawShadow(g2d, p, shape.getDeltaShadow(), dpiFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,157 +0,0 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ugraphic.g2d;
|
||||
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
|
||||
import net.sourceforge.plantuml.golem.MinMaxDouble;
|
||||
import net.sourceforge.plantuml.ugraphic.UDriver;
|
||||
import net.sourceforge.plantuml.ugraphic.UParam;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.USegment;
|
||||
import net.sourceforge.plantuml.ugraphic.USegmentType;
|
||||
import net.sourceforge.plantuml.ugraphic.UShape;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorGradient;
|
||||
|
||||
public class DriverPathG2dLegacy extends DriverShadowedG2d implements UDriver<Graphics2D> {
|
||||
|
||||
private final double dpiFactor;
|
||||
|
||||
public DriverPathG2dLegacy(double dpiFactor) {
|
||||
this.dpiFactor = dpiFactor;
|
||||
}
|
||||
|
||||
public void draw(UShape ushape, final double x, final double y, ColorMapper mapper, UParam param, Graphics2D g2d) {
|
||||
final UPath shape = (UPath) ushape;
|
||||
DriverLineG2d.manageStroke(param, g2d);
|
||||
|
||||
final Path2D.Double p = new Path2D.Double();
|
||||
boolean hasBezier = false;
|
||||
final MinMaxDouble minMax = new MinMaxDouble();
|
||||
minMax.manage(x, y);
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
p.moveTo(x + coord[0], y + coord[1]);
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
p.lineTo(x + coord[0], y + coord[1]);
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_CUBICTO) {
|
||||
p.curveTo(x + coord[0], y + coord[1], x + coord[2], y + coord[3], x + coord[4], y + coord[5]);
|
||||
minMax.manage(x + coord[4], y + coord[5]);
|
||||
hasBezier = true;
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
if (shape.isOpenIconic()) {
|
||||
p.closePath();
|
||||
g2d.setColor(mapper.toColor(param.getColor()));
|
||||
g2d.fill(p);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shadow
|
||||
if (shape.getDeltaShadow() != 0) {
|
||||
if (hasBezier) {
|
||||
drawShadow(g2d, p, shape.getDeltaShadow(), dpiFactor);
|
||||
} else {
|
||||
double lastX = 0;
|
||||
double lastY = 0;
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
// Cast float for Java 1.5
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
final Shape line = new Line2D.Double(lastX, lastY, x + coord[0], y + coord[1]);
|
||||
drawShadow(g2d, line, shape.getDeltaShadow(), dpiFactor);
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final HColor back = param.getBackcolor();
|
||||
if (back instanceof HColorGradient) {
|
||||
final HColorGradient gr = (HColorGradient) back;
|
||||
final char policy = gr.getPolicy();
|
||||
final GradientPaint paint;
|
||||
if (policy == '|') {
|
||||
paint = new GradientPaint((float) minMax.getMinX(), (float) minMax.getMaxY() / 2,
|
||||
mapper.toColor(gr.getColor1()), (float) minMax.getMaxX(), (float) minMax.getMaxY() / 2,
|
||||
mapper.toColor(gr.getColor2()));
|
||||
} else if (policy == '\\') {
|
||||
paint = new GradientPaint((float) minMax.getMinX(), (float) minMax.getMaxY(), mapper.toColor(gr
|
||||
.getColor1()), (float) minMax.getMaxX(), (float) minMax.getMinY(), mapper.toColor(gr
|
||||
.getColor2()));
|
||||
} else if (policy == '-') {
|
||||
paint = new GradientPaint((float) minMax.getMaxX() / 2, (float) minMax.getMinY(),
|
||||
mapper.toColor(gr.getColor1()), (float) minMax.getMaxX() / 2, (float) minMax.getMaxY(),
|
||||
mapper.toColor(gr.getColor2()));
|
||||
} else {
|
||||
// for /
|
||||
paint = new GradientPaint((float) x, (float) y, mapper.toColor(gr.getColor1()),
|
||||
(float) minMax.getMaxX(), (float) minMax.getMaxY(), mapper.toColor(gr.getColor2()));
|
||||
}
|
||||
g2d.setPaint(paint);
|
||||
g2d.fill(p);
|
||||
} else if (back != null) {
|
||||
g2d.setColor(mapper.toColor(back));
|
||||
g2d.fill(p);
|
||||
}
|
||||
|
||||
if (param.getColor() != null) {
|
||||
g2d.setColor(mapper.toColor(param.getColor()));
|
||||
g2d.draw(p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2020, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* http://plantuml.com/patreon (only 1$ per month!)
|
||||
* http://plantuml.com/paypal
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
*
|
||||
* Original Author: Arnaud Roques
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.ugraphic.g2d;
|
||||
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
import net.sourceforge.plantuml.golem.MinMaxDouble;
|
||||
import net.sourceforge.plantuml.ugraphic.UDriver;
|
||||
import net.sourceforge.plantuml.ugraphic.UParam;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.USegment;
|
||||
import net.sourceforge.plantuml.ugraphic.USegmentType;
|
||||
import net.sourceforge.plantuml.ugraphic.UShape;
|
||||
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColorGradient;
|
||||
|
||||
public class DriverPathOldG2d extends DriverShadowedG2d implements UDriver<Graphics2D> {
|
||||
|
||||
private final double dpiFactor;
|
||||
|
||||
public DriverPathOldG2d(double dpiFactor) {
|
||||
this.dpiFactor = dpiFactor;
|
||||
}
|
||||
|
||||
public void draw(UShape ushape, final double x, final double y, ColorMapper mapper, UParam param, Graphics2D g2d) {
|
||||
final UPath shape = (UPath) ushape;
|
||||
DriverLineG2d.manageStroke(param, g2d);
|
||||
|
||||
final GeneralPath p = new GeneralPath();
|
||||
boolean hasBezier = false;
|
||||
final MinMaxDouble minMax = new MinMaxDouble();
|
||||
minMax.manage(x, y);
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
// Cast float for Java 1.5
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
p.moveTo((float) (x + coord[0]), (float) (y + coord[1]));
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
p.lineTo((float) (x + coord[0]), (float) (y + coord[1]));
|
||||
minMax.manage(x + coord[0], y + coord[1]);
|
||||
} else if (type == USegmentType.SEG_CUBICTO) {
|
||||
p.curveTo((float) (x + coord[0]), (float) (y + coord[1]), (float) (x + coord[2]),
|
||||
(float) (y + coord[3]), (float) (x + coord[4]), (float) (y + coord[5]));
|
||||
minMax.manage(x + coord[4], y + coord[5]);
|
||||
hasBezier = true;
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
// bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x +
|
||||
// bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y
|
||||
// + bez.ctrly2, x + bez.x2, y + bez.y2);
|
||||
// p.append(bez, true);
|
||||
}
|
||||
// p.closePath();
|
||||
|
||||
// Shadow
|
||||
if (shape.getDeltaShadow() != 0) {
|
||||
if (hasBezier) {
|
||||
drawShadow(g2d, p, shape.getDeltaShadow(), dpiFactor);
|
||||
} else {
|
||||
double lastX = 0;
|
||||
double lastY = 0;
|
||||
for (USegment seg : shape) {
|
||||
final USegmentType type = seg.getSegmentType();
|
||||
final double coord[] = seg.getCoord();
|
||||
// Cast float for Java 1.5
|
||||
if (type == USegmentType.SEG_MOVETO) {
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else if (type == USegmentType.SEG_LINETO) {
|
||||
final Shape line = new Line2D.Double(lastX, lastY, x + coord[0], y + coord[1]);
|
||||
drawShadow(g2d, line, shape.getDeltaShadow(), dpiFactor);
|
||||
lastX = x + coord[0];
|
||||
lastY = y + coord[1];
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final HColor back = param.getBackcolor();
|
||||
if (back instanceof HColorGradient) {
|
||||
final HColorGradient gr = (HColorGradient) back;
|
||||
final char policy = gr.getPolicy();
|
||||
final GradientPaint paint;
|
||||
if (policy == '|') {
|
||||
paint = new GradientPaint((float) minMax.getMinX(), (float) minMax.getMaxY() / 2,
|
||||
mapper.toColor(gr.getColor1()), (float) minMax.getMaxX(), (float) minMax.getMaxY() / 2,
|
||||
mapper.toColor(gr.getColor2()));
|
||||
} else if (policy == '\\') {
|
||||
paint = new GradientPaint((float) minMax.getMinX(), (float) minMax.getMaxY(), mapper.toColor(gr
|
||||
.getColor1()), (float) minMax.getMaxX(), (float) minMax.getMinY(), mapper.toColor(gr
|
||||
.getColor2()));
|
||||
} else if (policy == '-') {
|
||||
paint = new GradientPaint((float) minMax.getMaxX() / 2, (float) minMax.getMinY(),
|
||||
mapper.toColor(gr.getColor1()), (float) minMax.getMaxX() / 2, (float) minMax.getMaxY(),
|
||||
mapper.toColor(gr.getColor2()));
|
||||
} else {
|
||||
// for /
|
||||
paint = new GradientPaint((float) x, (float) y, mapper.toColor(gr.getColor1()),
|
||||
(float) minMax.getMaxX(), (float) minMax.getMaxY(), mapper.toColor(gr.getColor2()));
|
||||
}
|
||||
g2d.setPaint(paint);
|
||||
g2d.fill(p);
|
||||
} else if (back != null) {
|
||||
g2d.setColor(mapper.toColor(back));
|
||||
g2d.fill(p);
|
||||
}
|
||||
|
||||
if (param.getColor() != null) {
|
||||
g2d.setColor(mapper.toColor(param.getColor()));
|
||||
g2d.draw(p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -39,13 +39,9 @@ import java.awt.BasicStroke;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.EnsureVisible;
|
||||
import net.sourceforge.plantuml.ugraphic.MinMax;
|
||||
import net.sourceforge.plantuml.ugraphic.UDriver;
|
||||
import net.sourceforge.plantuml.ugraphic.UParam;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
@ -73,9 +69,6 @@ public class DriverPolygonG2d extends DriverShadowedG2d implements UDriver<Graph
|
||||
final GeneralPath path = new GeneralPath();
|
||||
|
||||
final HColor back = param.getBackcolor();
|
||||
final List<Line2D.Double> shadows = shape.getDeltaShadow() != 0 && HColorUtils.isTransparent(back)
|
||||
? new ArrayList<Line2D.Double>()
|
||||
: null;
|
||||
|
||||
Point2D.Double last = null;
|
||||
for (Point2D pt : shape.getPoints()) {
|
||||
@ -85,9 +78,6 @@ public class DriverPolygonG2d extends DriverShadowedG2d implements UDriver<Graph
|
||||
if (last == null) {
|
||||
path.moveTo((float) xp, (float) yp);
|
||||
} else {
|
||||
if (shadows != null) {
|
||||
shadows.add(new Line2D.Double(last.x, last.y, xp, yp));
|
||||
}
|
||||
path.lineTo((float) xp, (float) yp);
|
||||
}
|
||||
last = new Point2D.Double(xp, yp);
|
||||
@ -97,12 +87,12 @@ public class DriverPolygonG2d extends DriverShadowedG2d implements UDriver<Graph
|
||||
path.closePath();
|
||||
}
|
||||
|
||||
if (shadows != null) {
|
||||
for (Line2D.Double line : keepSome(shadows)) {
|
||||
drawOnlyLineShadow(g2d, line, shape.getDeltaShadow(), dpiFactor);
|
||||
if (shape.getDeltaShadow() != 0) {
|
||||
if (HColorUtils.isTransparent(back)) {
|
||||
drawOnlyLineShadowSpecial(g2d, path, shape.getDeltaShadow(), dpiFactor);
|
||||
} else {
|
||||
drawShadow(g2d, path, shape.getDeltaShadow(), dpiFactor);
|
||||
}
|
||||
} else if (shape.getDeltaShadow() != 0) {
|
||||
drawShadow(g2d, path, shape.getDeltaShadow(), dpiFactor);
|
||||
}
|
||||
|
||||
if (back instanceof HColorGradient) {
|
||||
@ -141,32 +131,4 @@ public class DriverPolygonG2d extends DriverShadowedG2d implements UDriver<Graph
|
||||
}
|
||||
}
|
||||
|
||||
private List<Line2D.Double> keepSome(List<Line2D.Double> shadows) {
|
||||
final List<Line2D.Double> result = new ArrayList<Line2D.Double>();
|
||||
MinMax minMax = MinMax.getEmpty(true);
|
||||
for (Line2D.Double line : shadows) {
|
||||
minMax = minMax.addPoint(line.x1, line.y1);
|
||||
minMax = minMax.addPoint(line.y2, line.y2);
|
||||
}
|
||||
for (Line2D.Double line : shadows) {
|
||||
if (keepMe(line, minMax.getMaxX(), minMax.getMaxY()))
|
||||
result.add(line);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean keepMe(Line2D.Double line, double maxX, double maxY) {
|
||||
if (line.x1 >= maxX && line.x2 >= maxX) {
|
||||
return true;
|
||||
}
|
||||
if (line.y1 >= maxY && line.y2 >= maxY) {
|
||||
return true;
|
||||
}
|
||||
final double margin = 10;
|
||||
if (line.x1 >= maxX - margin && line.x2 >= maxX - margin && line.y1 >= maxY - margin
|
||||
&& line.y2 >= maxY - margin) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.TexturePaint;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -89,10 +88,7 @@ public class DriverRectangleG2d extends DriverShadowedG2d implements UDriver<Gra
|
||||
// Shadow
|
||||
if (rect.getDeltaShadow() != 0) {
|
||||
if (HColorUtils.isTransparent(back)) {
|
||||
drawOnlyLineShadow(g2d, new Line2D.Double(x, y + rect.getHeight(), x + rect.getWidth(), y + rect.getHeight()),
|
||||
rect.getDeltaShadow(), dpiFactor);
|
||||
drawOnlyLineShadow(g2d, new Line2D.Double(x + rect.getWidth(), y, x + rect.getWidth(), y + rect.getHeight()),
|
||||
rect.getDeltaShadow(), dpiFactor);
|
||||
drawOnlyLineShadowSpecial(g2d, shape, rect.getDeltaShadow(), dpiFactor);
|
||||
} else {
|
||||
drawShadow(g2d, shape, rect.getDeltaShadow(), dpiFactor);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -111,7 +112,7 @@ public class DriverShadowedG2d {
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawOnlyLineShadow(Graphics2D g2d, Line2D.Double shape, double deltaShadow, double dpiFactor) {
|
||||
protected void drawOnlyLineShadow(Graphics2D g2d, Shape shape, double deltaShadow, double dpiFactor) {
|
||||
if (dpiFactor < 1) {
|
||||
dpiFactor = 1;
|
||||
}
|
||||
@ -145,4 +146,47 @@ public class DriverShadowedG2d {
|
||||
g2d.setTransform(at);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawOnlyLineShadowSpecial(Graphics2D g2d, Shape shape, double deltaShadow, double dpiFactor) {
|
||||
if (dpiFactor < 1) {
|
||||
dpiFactor = 1;
|
||||
}
|
||||
final Rectangle2D bounds = shape.getBounds2D();
|
||||
final double ww = bounds.getMaxX() - bounds.getMinX();
|
||||
final double hh = bounds.getMaxY() - bounds.getMinY();
|
||||
|
||||
final double w = (ww + deltaShadow * 2 + 6) * dpiFactor;
|
||||
final double h = (hh + deltaShadow * 2 + 6) * dpiFactor;
|
||||
BufferedImage destination = null;
|
||||
try {
|
||||
destination = new BufferedImage((int) w, (int) h, BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics2D gg = destination.createGraphics();
|
||||
gg.scale(dpiFactor, dpiFactor);
|
||||
gg.translate(deltaShadow - bounds.getMinX(), deltaShadow - bounds.getMinY());
|
||||
gg.draw(shape);
|
||||
gg.dispose();
|
||||
|
||||
final ConvolveOp simpleBlur = getConvolveOp(6, dpiFactor);
|
||||
destination = simpleBlur.filter(destination, null);
|
||||
} catch (OutOfMemoryError error) {
|
||||
Log.info("Warning: Cannot draw shadow, image too big.");
|
||||
} catch (Exception e) {
|
||||
Log.info("Warning: Cannot draw shadow: " + e);
|
||||
}
|
||||
if (destination != null) {
|
||||
final AffineTransform at = g2d.getTransform();
|
||||
g2d.scale(1 / dpiFactor, 1 / dpiFactor);
|
||||
final Shape sav = g2d.getClip();
|
||||
|
||||
Area full = new Area(new Rectangle2D.Double(0, 0, bounds.getMaxX() + deltaShadow * 2 + 6,
|
||||
bounds.getMaxY() + deltaShadow * 2 + 6));
|
||||
full.subtract(new Area(shape));
|
||||
g2d.setClip(full);
|
||||
|
||||
g2d.drawImage(destination, (int) (bounds.getMinX() * dpiFactor), (int) (bounds.getMinY() * dpiFactor),
|
||||
null);
|
||||
g2d.setClip(sav);
|
||||
g2d.setTransform(at);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class Version {
|
||||
private static final int MAJOR_SEPARATOR = 1000000;
|
||||
|
||||
public static int version() {
|
||||
return 1202012;
|
||||
return 1202013;
|
||||
}
|
||||
|
||||
public static int versionPatched() {
|
||||
@ -93,7 +93,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static long compileTime() {
|
||||
return 1591440855351L;
|
||||
return 1592051198896L;
|
||||
}
|
||||
|
||||
public static String compileTimeString() {
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user