2011-08-08 17:48:29 +00:00
|
|
|
/* ========================================================================
|
|
|
|
* PlantUML : a free UML diagram generator
|
|
|
|
* ========================================================================
|
|
|
|
*
|
2023-02-22 18:43:48 +00:00
|
|
|
* (C) Copyright 2009-2024, Arnaud Roques
|
2011-08-08 17:48:29 +00:00
|
|
|
*
|
2023-02-22 18:43:48 +00:00
|
|
|
* Project Info: https://plantuml.com
|
2022-02-15 18:11:51 +00:00
|
|
|
*
|
2017-03-15 19:13:31 +00:00
|
|
|
* If you like this project or if you find it useful, you can support us at:
|
2022-02-15 18:11:51 +00:00
|
|
|
*
|
2023-02-22 18:43:48 +00:00
|
|
|
* https://plantuml.com/patreon (only 1$ per month!)
|
|
|
|
* https://plantuml.com/paypal
|
2022-02-15 18:11:51 +00:00
|
|
|
*
|
2011-08-08 17:48:29 +00:00
|
|
|
* 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
|
2013-12-10 19:36:50 +00:00
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
2011-08-08 17:48:29 +00:00
|
|
|
* 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
|
|
|
|
*
|
2022-02-15 18:11:51 +00:00
|
|
|
*
|
2011-08-08 17:48:29 +00:00
|
|
|
*/
|
|
|
|
package net.sourceforge.plantuml.svek;
|
|
|
|
|
2022-02-16 18:59:44 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.EnumMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Objects;
|
|
|
|
import java.util.Set;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-12-17 11:10:05 +00:00
|
|
|
import net.sourceforge.plantuml.StringUtils;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.abel.CucaNote;
|
|
|
|
import net.sourceforge.plantuml.abel.Entity;
|
|
|
|
import net.sourceforge.plantuml.abel.Hideable;
|
|
|
|
import net.sourceforge.plantuml.abel.LeafType;
|
|
|
|
import net.sourceforge.plantuml.abel.Link;
|
|
|
|
import net.sourceforge.plantuml.abel.LinkArrow;
|
|
|
|
import net.sourceforge.plantuml.abel.NoteLinkStrategy;
|
2016-07-04 19:06:50 +00:00
|
|
|
import net.sourceforge.plantuml.cucadiagram.EntityPort;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.decoration.LinkDecor;
|
|
|
|
import net.sourceforge.plantuml.decoration.LinkMiddleDecor;
|
|
|
|
import net.sourceforge.plantuml.decoration.LinkType;
|
|
|
|
import net.sourceforge.plantuml.decoration.Rainbow;
|
2020-05-17 21:15:50 +00:00
|
|
|
import net.sourceforge.plantuml.descdiagram.command.StringWithArrow;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.dot.DotSplines;
|
|
|
|
import net.sourceforge.plantuml.dot.GraphvizVersion;
|
2023-02-02 17:59:43 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.UGroupType;
|
|
|
|
import net.sourceforge.plantuml.klimt.UStroke;
|
|
|
|
import net.sourceforge.plantuml.klimt.UTranslate;
|
|
|
|
import net.sourceforge.plantuml.klimt.color.ColorType;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.color.Colors;
|
2023-02-02 17:59:43 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.color.HColor;
|
|
|
|
import net.sourceforge.plantuml.klimt.color.HColors;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.creole.CreoleMode;
|
|
|
|
import net.sourceforge.plantuml.klimt.creole.Display;
|
|
|
|
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
2023-02-02 17:59:43 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
|
|
|
|
import net.sourceforge.plantuml.klimt.font.StringBounder;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.BezierUtils;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
|
2023-02-26 18:51:17 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.geom.MagneticBorder;
|
2023-02-02 17:59:43 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.geom.Moveable;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.PointAndAngle;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.Positionable;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.PositionableUtils;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.Side;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.klimt.geom.VerticalAlignment;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.XDimension2D;
|
|
|
|
import net.sourceforge.plantuml.klimt.geom.XPoint2D;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.DotPath;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.TextBlock;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.UDrawable;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.ULine;
|
|
|
|
import net.sourceforge.plantuml.klimt.shape.UPolygon;
|
|
|
|
import net.sourceforge.plantuml.skin.AlignmentParam;
|
|
|
|
import net.sourceforge.plantuml.skin.ColorParam;
|
|
|
|
import net.sourceforge.plantuml.skin.LineParam;
|
|
|
|
import net.sourceforge.plantuml.skin.Pragma;
|
|
|
|
import net.sourceforge.plantuml.skin.UmlDiagramType;
|
2018-10-21 19:44:14 +00:00
|
|
|
import net.sourceforge.plantuml.skin.VisibilityModifier;
|
|
|
|
import net.sourceforge.plantuml.skin.rose.Rose;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.stereo.Stereotype;
|
|
|
|
import net.sourceforge.plantuml.style.ISkinParam;
|
2021-03-07 12:23:24 +00:00
|
|
|
import net.sourceforge.plantuml.style.StyleBuilder;
|
2016-03-06 16:47:34 +00:00
|
|
|
import net.sourceforge.plantuml.svek.extremity.Extremity;
|
2022-10-25 20:43:40 +00:00
|
|
|
import net.sourceforge.plantuml.svek.extremity.ExtremityArrow;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.svek.extremity.ExtremityFactory;
|
2017-02-01 18:55:51 +00:00
|
|
|
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryExtends;
|
2019-05-24 19:59:31 +00:00
|
|
|
import net.sourceforge.plantuml.svek.extremity.ExtremityOther;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.svek.image.EntityImageNoteLink;
|
2023-02-02 17:59:43 +00:00
|
|
|
import net.sourceforge.plantuml.url.Url;
|
2022-12-17 11:01:10 +00:00
|
|
|
import net.sourceforge.plantuml.utils.Direction;
|
|
|
|
import net.sourceforge.plantuml.utils.Log;
|
2023-02-22 18:43:48 +00:00
|
|
|
import net.sourceforge.plantuml.utils.Position;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
public class SvekLine implements Moveable, Hideable, GuideLine {
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
private static final XDimension2D CONSTRAINT_SPOT = new XDimension2D(10, 10);
|
2020-05-17 21:15:50 +00:00
|
|
|
|
2016-01-09 12:15:40 +00:00
|
|
|
private final Cluster ltail;
|
|
|
|
private final Cluster lhead;
|
2011-08-08 17:48:29 +00:00
|
|
|
private final Link link;
|
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
private final EntityPort startUid;
|
|
|
|
private final EntityPort endUid;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
|
|
|
private final TextBlock startTailText;
|
|
|
|
private final TextBlock endHeadText;
|
2015-09-28 20:42:17 +00:00
|
|
|
private final TextBlock labelText;
|
2016-09-29 19:51:18 +00:00
|
|
|
private boolean divideLabelWidthByTwo = false;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
|
|
|
private final int lineColor;
|
2011-09-07 20:41:58 +00:00
|
|
|
private final int noteLabelColor;
|
2011-08-08 17:48:29 +00:00
|
|
|
private final int startTailColor;
|
|
|
|
private final int endHeadColor;
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
private final StringBounder stringBounder;
|
|
|
|
private final Bibliotekon bibliotekon;
|
|
|
|
|
|
|
|
private DotPath dotPath;
|
|
|
|
|
2011-09-07 20:41:58 +00:00
|
|
|
private Positionable startTailLabelXY;
|
|
|
|
private Positionable endHeadLabelXY;
|
2015-09-28 20:42:17 +00:00
|
|
|
private Positionable labelXY;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
private UDrawable extremity1;
|
2023-02-26 18:51:17 +00:00
|
|
|
private UDrawable extremity2;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
private double dx;
|
|
|
|
private double dy;
|
|
|
|
|
|
|
|
private boolean opale;
|
|
|
|
private Cluster projectionCluster;
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private final Pragma pragma;
|
2020-03-18 10:50:02 +00:00
|
|
|
private final HColor backgroundColor;
|
2017-06-05 11:27:21 +00:00
|
|
|
private final boolean useRankSame;
|
2017-10-07 09:46:53 +00:00
|
|
|
private final UStroke defaultThickness;
|
2020-03-18 10:50:02 +00:00
|
|
|
private HColor arrowLollipopColor;
|
2020-02-18 21:24:31 +00:00
|
|
|
private final ISkinParam skinParam;
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2021-03-09 18:02:38 +00:00
|
|
|
private final double labelShield;
|
2019-06-26 19:24:49 +00:00
|
|
|
|
2022-12-16 16:20:14 +00:00
|
|
|
private final UmlDiagramType type;
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return super.toString() + " color=" + lineColor;
|
|
|
|
}
|
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
public Direction getArrowDirection() {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (getLinkArrow() == LinkArrow.BACKWARD)
|
2020-05-17 21:15:50 +00:00
|
|
|
return getArrowDirectionInternal().getInv();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
return getArrowDirectionInternal();
|
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
private Direction getArrowDirectionInternal() {
|
|
|
|
if (isAutolink()) {
|
|
|
|
final double startAngle = dotPath.getStartAngle();
|
|
|
|
return Direction.LEFT;
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D start = dotPath.getStartPoint();
|
|
|
|
final XPoint2D end = dotPath.getEndPoint();
|
2020-05-17 21:15:50 +00:00
|
|
|
final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY());
|
2022-01-19 21:35:53 +00:00
|
|
|
if (ang > -Math.PI / 4 && ang < Math.PI / 4)
|
2020-05-17 21:15:50 +00:00
|
|
|
return Direction.DOWN;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (ang > Math.PI * 3 / 4 || ang < -Math.PI * 3 / 4)
|
2020-05-17 21:15:50 +00:00
|
|
|
return Direction.UP;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
return end.getX() > start.getX() ? Direction.RIGHT : Direction.LEFT;
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2020-09-30 20:57:58 +00:00
|
|
|
public double getArrowDirection2() {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (getLinkArrow() == LinkArrow.BACKWARD)
|
2020-09-30 20:57:58 +00:00
|
|
|
return Math.PI + getArrowDirectionInternal2();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2020-09-30 20:57:58 +00:00
|
|
|
return getArrowDirectionInternal2();
|
|
|
|
}
|
|
|
|
|
|
|
|
private double getArrowDirectionInternal2() {
|
|
|
|
if (isAutolink()) {
|
|
|
|
final double startAngle = dotPath.getStartAngle();
|
|
|
|
return startAngle;
|
|
|
|
}
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D start = dotPath.getStartPoint();
|
|
|
|
final XPoint2D end = dotPath.getEndPoint();
|
2020-09-30 20:57:58 +00:00
|
|
|
final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY());
|
|
|
|
return ang;
|
|
|
|
}
|
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
private Cluster getCluster2(Bibliotekon bibliotekon, Entity entityMutable) {
|
2022-01-19 21:35:53 +00:00
|
|
|
for (Cluster cl : bibliotekon.allCluster())
|
|
|
|
if (cl.getGroups().contains(entityMutable))
|
2016-07-04 19:06:50 +00:00
|
|
|
return cl;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
public SvekLine(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder,
|
2022-08-26 16:00:28 +00:00
|
|
|
FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma, GraphvizVersion graphvizVersion) {
|
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
// ::comment when CORE
|
2022-10-05 20:32:57 +00:00
|
|
|
if (graphvizVersion.useShieldForQuantifier() && link.getLinkArg().getQuantifier1() != null)
|
2023-01-31 19:27:04 +00:00
|
|
|
link.getEntity1().ensureMargins(Margins.uniform(16));
|
2022-08-26 16:00:28 +00:00
|
|
|
|
2022-10-05 20:32:57 +00:00
|
|
|
if (graphvizVersion.useShieldForQuantifier() && link.getLinkArg().getQuantifier2() != null)
|
2023-01-31 19:27:04 +00:00
|
|
|
link.getEntity2().ensureMargins(Margins.uniform(16));
|
|
|
|
// ::done
|
2022-08-26 16:00:28 +00:00
|
|
|
|
|
|
|
if (link.getLinkArg().getKal1() != null)
|
2023-02-06 21:04:53 +00:00
|
|
|
this.kal1 = new Kal(this, link.getLinkArg().getKal1(), font, skinParam, (Entity) link.getEntity1(), link,
|
2022-12-16 16:20:14 +00:00
|
|
|
stringBounder);
|
2022-08-26 16:00:28 +00:00
|
|
|
|
|
|
|
if (link.getLinkArg().getKal2() != null)
|
2023-02-06 21:04:53 +00:00
|
|
|
this.kal2 = new Kal(this, link.getLinkArg().getKal2(), font, skinParam, (Entity) link.getEntity2(), link,
|
2022-12-16 16:20:14 +00:00
|
|
|
stringBounder);
|
2016-07-04 19:06:50 +00:00
|
|
|
|
2022-12-16 16:20:14 +00:00
|
|
|
this.type = skinParam.getUmlDiagramType();
|
2021-05-14 08:42:57 +00:00
|
|
|
this.link = Objects.requireNonNull(link);
|
2020-02-18 21:24:31 +00:00
|
|
|
this.skinParam = skinParam;
|
2019-06-26 19:24:49 +00:00
|
|
|
// this.umlType = link.getUmlDiagramType();
|
2017-06-05 11:27:21 +00:00
|
|
|
this.useRankSame = skinParam.useRankSame();
|
2016-07-04 19:06:50 +00:00
|
|
|
this.startUid = link.getEntityPort1(bibliotekon);
|
|
|
|
this.endUid = link.getEntityPort2(bibliotekon);
|
|
|
|
|
|
|
|
Cluster ltail = null;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (startUid.startsWith(Cluster.CENTER_ID))
|
2016-07-04 19:06:50 +00:00
|
|
|
ltail = getCluster2(bibliotekon, link.getEntity1());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
Cluster lhead = null;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (endUid.startsWith(Cluster.CENTER_ID))
|
2016-07-04 19:06:50 +00:00
|
|
|
lhead = getCluster2(bibliotekon, link.getEntity2());
|
|
|
|
|
2015-09-28 20:42:17 +00:00
|
|
|
if (link.getColors() != null) {
|
|
|
|
skinParam = link.getColors().mute(skinParam);
|
2020-05-17 21:15:50 +00:00
|
|
|
font = font.mute(link.getColors());
|
2015-09-28 20:42:17 +00:00
|
|
|
}
|
2021-11-08 13:56:52 +00:00
|
|
|
this.backgroundColor = skinParam.getBackgroundColor();
|
2017-10-07 09:46:53 +00:00
|
|
|
this.defaultThickness = skinParam.getThickness(LineParam.arrow, null);
|
|
|
|
this.arrowLollipopColor = skinParam.getHtmlColor(ColorParam.arrowLollipop, null, false);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (arrowLollipopColor == null)
|
2021-11-05 05:03:15 +00:00
|
|
|
this.arrowLollipopColor = backgroundColor;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
this.pragma = pragma;
|
2013-12-10 19:36:50 +00:00
|
|
|
this.bibliotekon = bibliotekon;
|
2011-08-08 17:48:29 +00:00
|
|
|
this.stringBounder = stringBounder;
|
|
|
|
this.ltail = ltail;
|
|
|
|
this.lhead = lhead;
|
|
|
|
|
|
|
|
this.lineColor = colorSequence.getValue();
|
2011-09-07 20:41:58 +00:00
|
|
|
this.noteLabelColor = colorSequence.getValue();
|
2011-08-08 17:48:29 +00:00
|
|
|
this.startTailColor = colorSequence.getValue();
|
|
|
|
this.endHeadColor = colorSequence.getValue();
|
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
TextBlock labelOnly;
|
2015-07-11 09:32:49 +00:00
|
|
|
if (Display.isNull(link.getLabel())) {
|
2020-05-17 21:15:50 +00:00
|
|
|
labelOnly = TextBlockUtils.EMPTY_TEXT_BLOCK;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL)
|
2020-05-17 21:15:50 +00:00
|
|
|
labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
} else {
|
2022-12-16 16:20:14 +00:00
|
|
|
final HorizontalAlignment alignment = getMessageTextAlignment(type, skinParam);
|
2020-05-17 21:15:50 +00:00
|
|
|
final boolean hasSeveralGuideLines = link.getLabel().hasSeveralGuideLines();
|
|
|
|
final TextBlock block;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (hasSeveralGuideLines)
|
2020-05-17 21:15:50 +00:00
|
|
|
block = StringWithArrow.addSeveralMagicArrows(link.getLabel(), this, font, alignment, skinParam);
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2022-08-24 16:46:33 +00:00
|
|
|
block = link.getLabel().create0(font, alignment, skinParam, skinParam.maxMessageSize(),
|
|
|
|
CreoleMode.SIMPLE_LINE, null, null);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
labelOnly = addVisibilityModifier(block, link, skinParam);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL && hasSeveralGuideLines == false)
|
2020-05-17 21:15:50 +00:00
|
|
|
labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-09-06 08:49:43 +00:00
|
|
|
final CucaNote note = link.getNote();
|
|
|
|
if (note == null) {
|
|
|
|
labelText = labelOnly;
|
2011-09-07 20:41:58 +00:00
|
|
|
} else {
|
2022-09-06 08:49:43 +00:00
|
|
|
final TextBlock noteOnly = new EntityImageNoteLink(note.getDisplay(), note.getColors(), skinParam,
|
|
|
|
link.getStyleBuilder());
|
|
|
|
if (note.getStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED
|
|
|
|
|| note.getStrategy() == NoteLinkStrategy.HALF_PRINTED_FULL)
|
2016-09-29 19:51:18 +00:00
|
|
|
divideLabelWidthByTwo = true;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-09-06 08:49:43 +00:00
|
|
|
if (note.getPosition() == Position.LEFT)
|
|
|
|
labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER);
|
|
|
|
else if (note.getPosition() == Position.RIGHT)
|
|
|
|
labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER);
|
|
|
|
else if (note.getPosition() == Position.TOP)
|
|
|
|
labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER);
|
|
|
|
else
|
|
|
|
labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER);
|
2011-09-07 20:41:58 +00:00
|
|
|
|
2022-09-06 08:49:43 +00:00
|
|
|
}
|
2011-09-07 20:41:58 +00:00
|
|
|
|
2022-10-05 20:32:57 +00:00
|
|
|
if (link.getQuantifier1() == null)
|
2011-08-08 17:48:29 +00:00
|
|
|
startTailText = null;
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2022-10-05 20:32:57 +00:00
|
|
|
startTailText = Display.getWithNewlines(link.getQuantifier1()).create(font, HorizontalAlignment.CENTER,
|
2015-09-28 20:42:17 +00:00
|
|
|
skinParam);
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-10-05 20:32:57 +00:00
|
|
|
if (link.getQuantifier2() == null)
|
2011-08-08 17:48:29 +00:00
|
|
|
endHeadText = null;
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2022-10-05 20:32:57 +00:00
|
|
|
endHeadText = Display.getWithNewlines(link.getQuantifier2()).create(font, HorizontalAlignment.CENTER,
|
2015-09-28 20:42:17 +00:00
|
|
|
skinParam);
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.getType().getMiddleDecor() == LinkMiddleDecor.NONE)
|
2021-03-09 18:02:38 +00:00
|
|
|
this.labelShield = 0;
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2021-03-09 18:02:38 +00:00
|
|
|
this.labelShield = 7;
|
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-08-26 16:00:28 +00:00
|
|
|
private Kal kal1;
|
|
|
|
private Kal kal2;
|
2022-08-24 16:46:33 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
private TextBlock addVisibilityModifier(TextBlock block, Link link, ISkinParam skinParam) {
|
2018-10-21 19:44:14 +00:00
|
|
|
final VisibilityModifier visibilityModifier = link.getVisibilityModifier();
|
|
|
|
if (visibilityModifier != null) {
|
|
|
|
final Rose rose = new Rose();
|
2020-03-18 10:50:02 +00:00
|
|
|
final HColor fore = rose.getHtmlColor(skinParam, visibilityModifier.getForeground());
|
2018-10-21 19:44:14 +00:00
|
|
|
TextBlock visibility = visibilityModifier.getUBlock(skinParam.classAttributeIconSize(), fore, null, false);
|
|
|
|
visibility = TextBlockUtils.withMargin(visibility, 0, 1, 2, 0);
|
2020-05-17 21:15:50 +00:00
|
|
|
block = TextBlockUtils.mergeLR(visibility, block, VerticalAlignment.CENTER);
|
2018-10-21 19:44:14 +00:00
|
|
|
}
|
2020-05-17 21:15:50 +00:00
|
|
|
final double marginLabel = startUid.equalsId(endUid) ? 6 : 1;
|
|
|
|
return TextBlockUtils.withMargin(block, marginLabel, marginLabel);
|
2018-10-21 19:44:14 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 19:24:49 +00:00
|
|
|
private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (umlDiagramType == UmlDiagramType.STATE)
|
2021-06-27 16:50:40 +00:00
|
|
|
return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false, null);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2019-06-26 19:24:49 +00:00
|
|
|
return skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER);
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public boolean hasNoteLabelText() {
|
2020-05-17 21:15:50 +00:00
|
|
|
return labelText != null && labelText != TextBlockUtils.EMPTY_TEXT_BLOCK;
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private LinkArrow getLinkArrow() {
|
|
|
|
return link.getLinkArrow();
|
|
|
|
}
|
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
// ::comment when CORE
|
2021-08-30 17:13:54 +00:00
|
|
|
public void appendLine(GraphvizVersion graphvizVersion, StringBuilder sb, DotMode dotMode, DotSplines dotSplines) {
|
2013-12-10 19:36:50 +00:00
|
|
|
// Log.println("inverted=" + isInverted());
|
|
|
|
// if (isInverted()) {
|
|
|
|
// sb.append(endUid);
|
|
|
|
// sb.append("->");
|
|
|
|
// sb.append(startUid);
|
|
|
|
// } else {
|
2016-07-04 19:06:50 +00:00
|
|
|
sb.append(startUid.getFullString());
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("->");
|
2016-07-04 19:06:50 +00:00
|
|
|
sb.append(endUid.getFullString());
|
2013-12-10 19:36:50 +00:00
|
|
|
// }
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("[");
|
2016-01-30 12:20:07 +00:00
|
|
|
final LinkType linkType = link.getTypePatchCluster();
|
2015-04-07 18:18:37 +00:00
|
|
|
String decoration = linkType.getSpecificDecorationSvek();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (decoration.length() > 0 && decoration.endsWith(",") == false)
|
2011-08-08 17:48:29 +00:00
|
|
|
decoration += ",";
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(decoration);
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
int length = link.getLength();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (graphvizVersion.ignoreHorizontalLinks() && length == 1)
|
2018-05-01 17:26:04 +00:00
|
|
|
length = 2;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2017-06-05 11:27:21 +00:00
|
|
|
if (useRankSame) {
|
|
|
|
if (pragma.horizontalLineBetweenDifferentPackageAllowed() || link.isInvis() || length != 1) {
|
|
|
|
// if (graphvizVersion.isJs() == false) {
|
|
|
|
sb.append("minlen=" + (length - 1));
|
|
|
|
sb.append(",");
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
} else {
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("minlen=" + (length - 1));
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(",");
|
|
|
|
}
|
2022-02-17 18:27:32 +00:00
|
|
|
sb.append("color=\"" + StringUtils.sharp000000(lineColor) + "\"");
|
2020-05-17 21:15:50 +00:00
|
|
|
if (hasNoteLabelText() || link.getLinkConstraint() != null) {
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(",");
|
2021-08-30 17:13:54 +00:00
|
|
|
if (graphvizVersion.useXLabelInsteadOfLabel() || dotMode == DotMode.NO_LEFT_RIGHT_AND_XLABEL
|
|
|
|
|| dotSplines == DotSplines.ORTHO) {
|
2016-06-19 14:16:41 +00:00
|
|
|
sb.append("xlabel=<");
|
|
|
|
} else {
|
|
|
|
sb.append("label=<");
|
|
|
|
}
|
2022-09-12 20:08:34 +00:00
|
|
|
XDimension2D dimNote = hasNoteLabelText() ? labelText.calculateDimension(stringBounder) : CONSTRAINT_SPOT;
|
2022-11-04 17:36:03 +00:00
|
|
|
dimNote = dimNote.delta(2 * labelShield);
|
2021-03-09 18:02:38 +00:00
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
appendTable(sb, eventuallyDivideByTwo(dimNote), noteLabelColor, graphvizVersion);
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(">");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (startTailText != null) {
|
|
|
|
sb.append(",");
|
|
|
|
sb.append("taillabel=<");
|
2016-06-19 14:16:41 +00:00
|
|
|
appendTable(sb, startTailText.calculateDimension(stringBounder), startTailColor, graphvizVersion);
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(">");
|
|
|
|
}
|
|
|
|
if (endHeadText != null) {
|
|
|
|
sb.append(",");
|
|
|
|
sb.append("headlabel=<");
|
2016-06-19 14:16:41 +00:00
|
|
|
appendTable(sb, endHeadText.calculateDimension(stringBounder), endHeadColor, graphvizVersion);
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(">");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (link.isInvis()) {
|
|
|
|
sb.append(",");
|
|
|
|
sb.append("style=invis");
|
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.isConstraint() == false || link.hasTwoEntryPointsSameContainer())
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(",constraint=false");
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.getSametail() != null)
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(",sametail=" + link.getSametail());
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("];");
|
|
|
|
SvekUtils.println(sb);
|
|
|
|
}
|
2023-01-31 19:27:04 +00:00
|
|
|
// ::done
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
private XDimension2D eventuallyDivideByTwo(XDimension2D dim) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (divideLabelWidthByTwo)
|
2022-09-12 20:08:34 +00:00
|
|
|
return new XDimension2D(dim.getWidth() / 2, dim.getHeight());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2016-09-29 19:51:18 +00:00
|
|
|
return dim;
|
|
|
|
}
|
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
public String rankSame() {
|
2013-12-10 19:36:50 +00:00
|
|
|
// if (graphvizVersion == GraphvizVersion.V2_34_0) {
|
|
|
|
// return null;
|
|
|
|
// }
|
2016-06-19 14:16:41 +00:00
|
|
|
if (pragma.horizontalLineBetweenDifferentPackageAllowed() == false && link.getLength() == 1
|
|
|
|
/* && graphvizVersion.isJs() == false */) {
|
2016-07-04 19:06:50 +00:00
|
|
|
return "{rank=same; " + getStartUidPrefix() + "; " + getEndUidPrefix() + "}";
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
public static void appendTable(StringBuilder sb, XDimension2D dim, int col, GraphvizVersion graphvizVersion) {
|
2011-08-08 17:48:29 +00:00
|
|
|
final int w = (int) dim.getWidth();
|
|
|
|
final int h = (int) dim.getHeight();
|
|
|
|
appendTable(sb, w, h, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void appendTable(StringBuilder sb, int w, int h, int col) {
|
|
|
|
sb.append("<TABLE ");
|
2022-02-17 18:27:32 +00:00
|
|
|
sb.append("BGCOLOR=\"" + StringUtils.sharp000000(col) + "\" ");
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("FIXEDSIZE=\"TRUE\" WIDTH=\"" + w + "\" HEIGHT=\"" + h + "\">");
|
|
|
|
sb.append("<TR");
|
|
|
|
sb.append(">");
|
|
|
|
sb.append("<TD");
|
|
|
|
// sb.append(" FIXEDSIZE=\"TRUE\" WIDTH=\"" + 0 + "\" HEIGHT=\"" + 0 +
|
|
|
|
// "\"");
|
|
|
|
sb.append(">");
|
|
|
|
sb.append("</TD>");
|
|
|
|
sb.append("</TR>");
|
|
|
|
sb.append("</TABLE>");
|
|
|
|
}
|
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
public final String getStartUidPrefix() {
|
|
|
|
return startUid.getPrefix();
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
public final String getEndUidPrefix() {
|
|
|
|
return endUid.getPrefix();
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2023-02-26 18:51:17 +00:00
|
|
|
private UDrawable getExtremity(final XPoint2D center, LinkDecor decor, PointListIterator pointListIterator,
|
2021-02-02 10:12:15 +00:00
|
|
|
double angle, Cluster cluster, SvekNode nodeContact) {
|
2016-06-19 14:16:41 +00:00
|
|
|
final ExtremityFactory extremityFactory = decor.getExtremityFactory(backgroundColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2016-03-06 16:47:34 +00:00
|
|
|
if (cluster != null) {
|
2016-01-09 12:15:40 +00:00
|
|
|
if (extremityFactory != null) {
|
|
|
|
// System.err.println("angle=" + angle * 180 / Math.PI);
|
2016-12-14 21:01:03 +00:00
|
|
|
return extremityFactory.createUDrawable(center, angle, null);
|
2016-01-09 12:15:40 +00:00
|
|
|
}
|
2022-01-19 21:35:53 +00:00
|
|
|
if (decor == LinkDecor.EXTENDS)
|
2017-02-01 18:55:51 +00:00
|
|
|
return new ExtremityFactoryExtends(backgroundColor).createUDrawable(center, angle, null);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2016-01-09 12:15:40 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
if (extremityFactory != null) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final List<XPoint2D> points = pointListIterator.next();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (points.size() == 0)
|
2017-06-05 11:27:21 +00:00
|
|
|
return extremityFactory.createUDrawable(center, angle, null);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D p0 = points.get(0);
|
|
|
|
final XPoint2D p1 = points.get(1);
|
|
|
|
final XPoint2D p2 = points.get(2);
|
2016-12-14 21:01:03 +00:00
|
|
|
Side side = null;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (nodeContact != null)
|
2023-02-26 18:51:17 +00:00
|
|
|
side = nodeContact.getRectangleArea().getClosestSide(p1);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2016-12-14 21:01:03 +00:00
|
|
|
return extremityFactory.createUDrawable(p0, p1, p2, side);
|
2017-06-05 11:27:21 +00:00
|
|
|
} else if (decor == LinkDecor.NONE) {
|
|
|
|
final UPolygon sh = new UPolygon(pointListIterator.cloneMe().next());
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D contact = sh.checkMiddleContactForSpecificTriangle(center);
|
2017-06-05 11:27:21 +00:00
|
|
|
if (contact != null) {
|
|
|
|
return new UDrawable() {
|
|
|
|
public void drawU(UGraphic ug) {
|
|
|
|
ULine line = new ULine(contact.getX() - center.getX(), contact.getY() - center.getY());
|
|
|
|
ug = ug.apply(new UTranslate(center));
|
|
|
|
ug.draw(line);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
} else if (decor != LinkDecor.NONE) {
|
2019-05-24 19:59:31 +00:00
|
|
|
final UPolygon sh = new UPolygon(pointListIterator.next());
|
|
|
|
return new ExtremityOther(sh);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-06-07 10:03:18 +00:00
|
|
|
public void solveLine(SvgResult fullSvg) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (this.link.isInvis())
|
2011-08-08 17:48:29 +00:00
|
|
|
return;
|
|
|
|
|
2018-03-09 21:37:34 +00:00
|
|
|
int idx = fullSvg.getIndexFromColor(this.lineColor);
|
2011-08-08 17:48:29 +00:00
|
|
|
if (idx == -1) {
|
2013-12-10 19:36:50 +00:00
|
|
|
return;
|
|
|
|
// throw new IllegalStateException();
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
2018-03-09 21:37:34 +00:00
|
|
|
idx = fullSvg.indexOf("d=\"", idx);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (idx == -1)
|
2011-08-08 17:48:29 +00:00
|
|
|
throw new IllegalStateException();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2018-03-09 21:37:34 +00:00
|
|
|
final int end = fullSvg.indexOf("\"", idx + 3);
|
|
|
|
final SvgResult path = fullSvg.substring(idx + 3, end);
|
2016-01-30 12:20:07 +00:00
|
|
|
|
2023-02-02 17:59:43 +00:00
|
|
|
if (path.isPathConsistent() == false)
|
2016-05-19 18:41:37 +00:00
|
|
|
return;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2023-02-02 17:59:43 +00:00
|
|
|
dotPath = path.toDotPath();
|
2016-03-06 16:47:34 +00:00
|
|
|
|
|
|
|
if (projectionCluster != null) {
|
2020-02-18 21:24:31 +00:00
|
|
|
// System.err.println("Line::solveLine1 projectionCluster=" +
|
|
|
|
// projectionCluster.getClusterPosition());
|
2016-08-25 20:45:37 +00:00
|
|
|
projectionCluster.manageEntryExitPoint(stringBounder);
|
2020-02-18 21:24:31 +00:00
|
|
|
// System.err.println("Line::solveLine2 projectionCluster=" +
|
|
|
|
// projectionCluster.getClusterPosition());
|
2016-03-06 16:47:34 +00:00
|
|
|
// if (lhead != null)
|
|
|
|
// System.err.println("Line::solveLine ltail=" + lhead.getClusterPosition());
|
|
|
|
// if (ltail != null)
|
|
|
|
// System.err.println("Line::solveLine ltail=" + ltail.getClusterPosition());
|
2016-01-09 12:15:40 +00:00
|
|
|
}
|
2023-02-26 18:51:17 +00:00
|
|
|
dotPath = dotPath.simulateCompound(lhead == null ? null : lhead.getRectangleArea(),
|
|
|
|
ltail == null ? null : ltail.getRectangleArea());
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2018-03-09 21:37:34 +00:00
|
|
|
final SvgResult lineSvg = fullSvg.substring(end);
|
|
|
|
PointListIterator pointListIterator = lineSvg.getPointsWithThisColor(lineColor);
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
final LinkType linkType = link.getType();
|
2023-02-26 18:51:17 +00:00
|
|
|
this.extremity1 = getExtremity(dotPath.getStartPoint(), linkType.getDecor2(), pointListIterator,
|
|
|
|
dotPath.getStartAngle() + Math.PI, ltail, getSvekNode1());
|
|
|
|
this.extremity2 = getExtremity(dotPath.getEndPoint(), linkType.getDecor1(), pointListIterator,
|
|
|
|
dotPath.getEndAngle(), lhead, getSvekNode2());
|
2019-04-21 20:40:01 +00:00
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.getEntity1().getLeafType() == LeafType.LOLLIPOP_HALF)
|
2023-02-26 18:51:17 +00:00
|
|
|
getSvekNode1().addImpact(dotPath.getStartAngle() + Math.PI);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (link.getEntity2().getLeafType() == LeafType.LOLLIPOP_HALF)
|
2023-02-26 18:51:17 +00:00
|
|
|
getSvekNode2().addImpact(dotPath.getEndAngle());
|
2019-04-21 20:40:01 +00:00
|
|
|
|
2016-03-06 16:47:34 +00:00
|
|
|
if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D p1 = ((Extremity) extremity1).somePoint();
|
|
|
|
final XPoint2D p2 = ((Extremity) extremity2).somePoint();
|
2016-03-06 16:47:34 +00:00
|
|
|
if (p1 != null && p2 != null) {
|
|
|
|
// http://plantuml.sourceforge.net/qa/?qa=4240/some-relations-point-wrong-direction-when-the-linetype-ortho
|
|
|
|
final double dist1start = p1.distance(dotPath.getStartPoint());
|
|
|
|
final double dist1end = p1.distance(dotPath.getEndPoint());
|
|
|
|
final double dist2start = p2.distance(dotPath.getStartPoint());
|
|
|
|
final double dist2end = p2.distance(dotPath.getEndPoint());
|
|
|
|
if (dist1start > dist1end && dist2end > dist2start) {
|
2018-03-09 21:37:34 +00:00
|
|
|
pointListIterator = lineSvg.getPointsWithThisColor(lineColor);
|
2023-02-26 18:51:17 +00:00
|
|
|
this.extremity2 = getExtremity(dotPath.getEndPoint(), linkType.getDecor1(), pointListIterator,
|
|
|
|
dotPath.getEndAngle(), lhead, getSvekNode2());
|
|
|
|
this.extremity1 = getExtremity(dotPath.getStartPoint(), linkType.getDecor2(), pointListIterator,
|
|
|
|
dotPath.getStartAngle() + Math.PI, ltail, getSvekNode1());
|
2016-03-06 16:47:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2011-09-07 20:41:58 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
if (hasNoteLabelText() || link.getLinkConstraint() != null) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D pos = getXY(fullSvg, this.noteLabelColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
if (pos != null) {
|
2020-06-07 10:03:18 +00:00
|
|
|
// corner1.manage(pos);
|
2020-05-17 21:15:50 +00:00
|
|
|
this.labelXY = hasNoteLabelText() ? TextBlockUtils.asPositionable(labelText, stringBounder, pos)
|
|
|
|
: TextBlockUtils.asPositionable(CONSTRAINT_SPOT, stringBounder, pos);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.startTailText != null) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D pos = getXY(fullSvg, this.startTailColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
if (pos != null) {
|
2020-06-07 10:03:18 +00:00
|
|
|
// corner1.manage(pos);
|
2013-12-10 19:36:50 +00:00
|
|
|
this.startTailLabelXY = TextBlockUtils.asPositionable(startTailText, stringBounder, pos);
|
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.endHeadText != null) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D pos = getXY(fullSvg, this.endHeadColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
if (pos != null) {
|
2020-06-07 10:03:18 +00:00
|
|
|
// corner1.manage(pos);
|
2013-12-10 19:36:50 +00:00
|
|
|
this.endHeadLabelXY = TextBlockUtils.asPositionable(endHeadText, stringBounder, pos);
|
2020-06-07 10:03:18 +00:00
|
|
|
// corner1.manage(pos.getX() - 15, pos.getY());
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (isOpalisable() == false)
|
2011-09-08 10:42:27 +00:00
|
|
|
setOpale(false);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-09-08 10:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-02-26 18:51:17 +00:00
|
|
|
private SvekNode getSvekNode2() {
|
|
|
|
return bibliotekon.getNode(link.getEntity2());
|
|
|
|
}
|
|
|
|
|
|
|
|
private SvekNode getSvekNode1() {
|
|
|
|
return bibliotekon.getNode(link.getEntity1());
|
|
|
|
}
|
|
|
|
|
2011-09-08 10:42:27 +00:00
|
|
|
private boolean isOpalisable() {
|
|
|
|
return dotPath.getBeziers().size() <= 1;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
private XPoint2D getXY(SvgResult svgResult, int color) {
|
2018-03-09 21:37:34 +00:00
|
|
|
final int idx = svgResult.getIndexFromColor(color);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (idx == -1)
|
2013-12-10 19:36:50 +00:00
|
|
|
return null;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2018-03-09 21:37:34 +00:00
|
|
|
return SvekUtils.getMinXY(svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS));
|
2011-08-08 17:48:29 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
public void drawU(UGraphic ug, Set<String> ids, UStroke suggestedStroke, Rainbow rainbow) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (opale)
|
2011-09-08 10:42:27 +00:00
|
|
|
return;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-04-07 16:53:33 +00:00
|
|
|
if (link.isInvis())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (dotPath == null) {
|
|
|
|
Log.info("DotPath is null for " + this);
|
|
|
|
return;
|
|
|
|
}
|
2022-09-14 18:12:03 +00:00
|
|
|
|
2019-08-26 17:07:21 +00:00
|
|
|
ug.draw(link.commentForSvg());
|
2022-02-16 18:59:44 +00:00
|
|
|
final Map<UGroupType, String> typeIDent = new EnumMap<>(UGroupType.class);
|
|
|
|
typeIDent.put(UGroupType.CLASS,
|
2023-02-06 21:04:53 +00:00
|
|
|
"link " + link.getEntity1().getName() + " " + link.getEntity2().getName() + " selected");
|
|
|
|
typeIDent.put(UGroupType.ID, "link_" + link.getEntity1().getName() + "_" + link.getEntity2().getName());
|
2022-02-15 18:11:51 +00:00
|
|
|
ug.startGroup(typeIDent);
|
2015-04-07 18:18:37 +00:00
|
|
|
double x = 0;
|
|
|
|
double y = 0;
|
2013-12-10 19:36:50 +00:00
|
|
|
final Url url = link.getUrl();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (url != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
ug.startUrl(url);
|
|
|
|
|
|
|
|
if (link.isAutoLinkOfAGroup()) {
|
2023-02-06 21:04:53 +00:00
|
|
|
final Cluster cl = bibliotekon.getCluster((Entity) link.getEntity1());
|
2016-03-06 16:47:34 +00:00
|
|
|
if (cl != null) {
|
2023-02-26 18:51:17 +00:00
|
|
|
x += cl.getRectangleArea().getWidth();
|
|
|
|
x -= dotPath.getStartPoint().getX() - cl.getRectangleArea().getMinX();
|
2016-03-06 16:47:34 +00:00
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 10:42:27 +00:00
|
|
|
x += dx;
|
|
|
|
y += dy;
|
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
HColor arrowHeadColor = rainbow.getArrowHeadColor();
|
|
|
|
HColor color = rainbow.getColor();
|
|
|
|
|
2015-09-28 20:42:17 +00:00
|
|
|
if (this.link.getColors() != null) {
|
2020-03-18 10:50:02 +00:00
|
|
|
final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE);
|
2022-10-25 20:43:40 +00:00
|
|
|
if (newColor != null) {
|
2015-09-28 20:42:17 +00:00
|
|
|
color = newColor;
|
2022-10-25 20:43:40 +00:00
|
|
|
arrowHeadColor = color;
|
|
|
|
}
|
|
|
|
} else if (this.link.getSpecificColor() != null) {
|
2011-08-08 17:48:29 +00:00
|
|
|
color = this.link.getSpecificColor();
|
2022-10-25 20:43:40 +00:00
|
|
|
arrowHeadColor = color;
|
|
|
|
}
|
2011-09-08 10:42:27 +00:00
|
|
|
|
2022-08-19 16:34:21 +00:00
|
|
|
ug = ug.apply(HColors.none().bg()).apply(color);
|
2015-04-07 18:18:37 +00:00
|
|
|
final LinkType linkType = link.getType();
|
2022-05-27 14:18:47 +00:00
|
|
|
UStroke stroke;
|
|
|
|
if (suggestedStroke == null || linkType.getStyle().isNormal() == false)
|
|
|
|
stroke = linkType.getStroke3(defaultThickness);
|
|
|
|
else
|
|
|
|
stroke = linkType.getStroke3(suggestedStroke);
|
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null)
|
2015-09-28 20:42:17 +00:00
|
|
|
stroke = link.getColors().getSpecificLineStroke();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2015-09-28 20:42:17 +00:00
|
|
|
ug = ug.apply(stroke);
|
2019-01-16 18:34:41 +00:00
|
|
|
// double moveEndY = 0;
|
2015-04-07 18:18:37 +00:00
|
|
|
|
2023-02-26 18:51:17 +00:00
|
|
|
DotPath todraw = dotPath.copy();
|
|
|
|
|
|
|
|
UTranslate magneticForce1 = new UTranslate();
|
|
|
|
if (getSvekNode1() != null) {
|
|
|
|
final MagneticBorder magneticBorder1 = getSvekNode1().getMagneticBorder();
|
|
|
|
magneticForce1 = magneticBorder1.getForceAt(ug.getStringBounder(), todraw.getStartPoint());
|
|
|
|
todraw.moveStartPoint(magneticForce1);
|
|
|
|
}
|
|
|
|
|
|
|
|
UTranslate magneticForce2 = new UTranslate();
|
|
|
|
if (getSvekNode2() != null) {
|
|
|
|
final MagneticBorder magneticBorder2 = getSvekNode2().getMagneticBorder();
|
|
|
|
magneticForce2 = magneticBorder2.getForceAt(ug.getStringBounder(), todraw.getEndPoint());
|
|
|
|
todraw.moveEndPoint(magneticForce2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// final MagneticBorder magneticBorder2 = getSvekNode2().getMagneticBorder();
|
|
|
|
|
|
|
|
// if (link.getEntity2().isGroup() && link.getEntity2().getUSymbol() instanceof USymbolFolder) {
|
|
|
|
// final Cluster endCluster = bibliotekon.getCluster((Entity) link.getEntity2());
|
|
|
|
// if (endCluster != null) {
|
|
|
|
// final double deltaFolderH = endCluster.checkFolderPosition(dotPath.getEndPoint(),
|
|
|
|
// ug.getStringBounder());
|
|
|
|
// todraw = dotPath.copy();
|
|
|
|
// todraw.moveEndPoint(0, deltaFolderH);
|
|
|
|
// // moveEndY = deltaFolderH;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) {
|
|
|
|
// // http://forum.plantuml.net/9421/arrow-inversion-with-skinparam-linetype-ortho-missing-arrow
|
|
|
|
// final XPoint2D p1 = ((Extremity) extremity1)
|
|
|
|
// .isTooSmallSoGiveThePointCloserToThisOne(todraw.getStartPoint());
|
|
|
|
// if (p1 != null)
|
|
|
|
// todraw.forceStartPoint(p1.getX(), p1.getY());
|
|
|
|
//
|
|
|
|
// final XPoint2D p2 = ((Extremity) extremity2).isTooSmallSoGiveThePointCloserToThisOne(todraw.getEndPoint());
|
|
|
|
// if (p2 != null)
|
|
|
|
// todraw.forceEndPoint(p2.getX(), p2.getY());
|
|
|
|
//
|
|
|
|
// }
|
2019-05-24 19:59:31 +00:00
|
|
|
|
2019-08-26 17:07:21 +00:00
|
|
|
final String comment = link.idCommentForSvg();
|
|
|
|
final String tmp = uniq(ids, comment);
|
2020-08-25 17:24:17 +00:00
|
|
|
todraw.setCommentAndCodeLine(tmp, link.getCodeLine());
|
2019-03-29 22:14:07 +00:00
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
drawRainbow(ug.apply(new UTranslate(x, y)), color, arrowHeadColor, todraw, link.getSupplementaryColors(),
|
2023-02-26 18:51:17 +00:00
|
|
|
stroke, magneticForce1, magneticForce2);
|
2016-03-06 16:47:34 +00:00
|
|
|
|
2020-04-19 16:04:39 +00:00
|
|
|
ug = ug.apply(new UStroke()).apply(color);
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2020-05-17 21:15:50 +00:00
|
|
|
if (hasNoteLabelText() && this.labelXY != null
|
2022-09-06 08:49:43 +00:00
|
|
|
&& (link.getNote() == null || link.getNote().getStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED))
|
2021-03-09 18:02:38 +00:00
|
|
|
this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX() + labelShield,
|
|
|
|
y + this.labelXY.getPosition().getY() + labelShield)));
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (this.startTailText != null && this.startTailLabelXY != null && this.startTailLabelXY.getPosition() != null)
|
2020-02-18 21:24:31 +00:00
|
|
|
this.startTailText.drawU(ug.apply(new UTranslate(x + this.startTailLabelXY.getPosition().getX(),
|
|
|
|
y + this.startTailLabelXY.getPosition().getY())));
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (this.endHeadText != null && this.endHeadLabelXY != null && this.endHeadLabelXY.getPosition() != null)
|
2020-02-18 21:24:31 +00:00
|
|
|
this.endHeadText.drawU(ug.apply(new UTranslate(x + this.endHeadLabelXY.getPosition().getX(),
|
|
|
|
y + this.endHeadLabelXY.getPosition().getY())));
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
if (linkType.getMiddleDecor() != LinkMiddleDecor.NONE) {
|
2013-12-10 19:36:50 +00:00
|
|
|
final PointAndAngle middle = dotPath.getMiddle();
|
|
|
|
final double angleRad = middle.getAngle();
|
|
|
|
final double angleDeg = -angleRad * 180.0 / Math.PI;
|
2021-01-20 13:33:07 +00:00
|
|
|
final UDrawable mi = linkType.getMiddleDecor().getMiddleFactory(arrowLollipopColor, backgroundColor)
|
2017-10-07 09:46:53 +00:00
|
|
|
.createUDrawable(angleDeg - 45);
|
2013-12-10 19:36:50 +00:00
|
|
|
mi.drawU(ug.apply(new UTranslate(x + middle.getX(), y + middle.getY())));
|
|
|
|
}
|
|
|
|
|
2022-01-19 21:35:53 +00:00
|
|
|
if (url != null)
|
2020-05-17 21:15:50 +00:00
|
|
|
ug.closeUrl();
|
2020-02-18 21:24:31 +00:00
|
|
|
|
|
|
|
if (link.getLinkConstraint() != null) {
|
|
|
|
final double xConstraint = x + this.labelXY.getPosition().getX();
|
|
|
|
final double yConstraint = y + this.labelXY.getPosition().getY();
|
|
|
|
// ug.apply(new UTranslate(xConstraint, yConstraint)).draw(new URectangle(10, 10));
|
2022-09-12 20:08:34 +00:00
|
|
|
final List<XPoint2D> square = getSquare(xConstraint, yConstraint);
|
2023-02-26 18:51:17 +00:00
|
|
|
final Set<XPoint2D> bez = todraw.sample();
|
2022-09-12 20:08:34 +00:00
|
|
|
XPoint2D minPt = null;
|
2020-02-18 21:24:31 +00:00
|
|
|
double minDist = Double.MAX_VALUE;
|
2022-09-12 20:08:34 +00:00
|
|
|
for (XPoint2D pt : square)
|
|
|
|
for (XPoint2D pt2 : bez) {
|
2020-02-18 21:24:31 +00:00
|
|
|
final double distance = pt2.distance(pt);
|
|
|
|
if (minPt == null || distance < minDist) {
|
|
|
|
minPt = pt;
|
|
|
|
minDist = distance;
|
|
|
|
}
|
|
|
|
}
|
2022-04-07 16:53:33 +00:00
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
link.getLinkConstraint().setPosition(link, minPt);
|
|
|
|
link.getLinkConstraint().drawMe(ug, skinParam);
|
|
|
|
}
|
2021-02-28 13:44:02 +00:00
|
|
|
|
2022-08-26 16:00:28 +00:00
|
|
|
ug.closeGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void computeKal() {
|
2022-08-24 16:46:33 +00:00
|
|
|
if (kal1 != null) {
|
2022-08-26 16:00:28 +00:00
|
|
|
final UTranslate tr = new UTranslate(dotPath.getStartPoint()).compose(new UTranslate(dx, dy));
|
2022-10-05 20:32:57 +00:00
|
|
|
kal1.setTranslate(tr, extremity1);
|
2022-08-26 16:00:28 +00:00
|
|
|
}
|
|
|
|
if (kal2 != null) {
|
|
|
|
final UTranslate tr = new UTranslate(dotPath.getEndPoint()).compose(new UTranslate(dx, dy));
|
2022-10-05 20:32:57 +00:00
|
|
|
kal2.setTranslate(tr, extremity2);
|
2022-08-24 16:46:33 +00:00
|
|
|
}
|
2020-02-18 21:24:31 +00:00
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
private List<XPoint2D> getSquare(double x, double y) {
|
|
|
|
final List<XPoint2D> result = new ArrayList<>();
|
|
|
|
result.add(new XPoint2D(x, y));
|
|
|
|
result.add(new XPoint2D(x + 5, y));
|
|
|
|
result.add(new XPoint2D(x + 10, y));
|
|
|
|
result.add(new XPoint2D(x, y + 5));
|
|
|
|
result.add(new XPoint2D(x + 10, y + 5));
|
|
|
|
result.add(new XPoint2D(x, y + 10));
|
|
|
|
result.add(new XPoint2D(x + 5, y + 10));
|
|
|
|
result.add(new XPoint2D(x + 10, y + 10));
|
2020-02-18 21:24:31 +00:00
|
|
|
return result;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2019-03-29 22:14:07 +00:00
|
|
|
private String uniq(final Set<String> ids, final String comment) {
|
|
|
|
boolean changed = ids.add(comment);
|
2022-04-07 16:53:33 +00:00
|
|
|
if (changed)
|
2019-03-29 22:14:07 +00:00
|
|
|
return comment;
|
2022-04-07 16:53:33 +00:00
|
|
|
|
2019-03-29 22:14:07 +00:00
|
|
|
int i = 1;
|
|
|
|
while (true) {
|
|
|
|
final String candidate = comment + "-" + i;
|
|
|
|
changed = ids.add(candidate);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (changed)
|
2019-03-29 22:14:07 +00:00
|
|
|
return candidate;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2019-03-29 22:14:07 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
private void drawRainbow(UGraphic ug, HColor color, HColor headColor, DotPath todraw,
|
2023-02-26 18:51:17 +00:00
|
|
|
List<Colors> supplementaryColors, UStroke stroke, UTranslate magneticForce1, UTranslate magneticForce2) {
|
2019-01-16 18:34:41 +00:00
|
|
|
ug.draw(todraw);
|
|
|
|
final LinkType linkType = link.getType();
|
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
if (headColor.isTransparent()) {
|
|
|
|
if (this.extremity1 instanceof ExtremityArrow) {
|
|
|
|
final UGraphic ugHead = ug.apply(color).apply(stroke.onlyThickness());
|
2023-02-26 18:51:17 +00:00
|
|
|
((ExtremityArrow) this.extremity1).drawLineIfTransparent(ugHead.apply(magneticForce1));
|
2022-10-25 20:43:40 +00:00
|
|
|
}
|
|
|
|
} else if (this.extremity1 != null) {
|
|
|
|
UGraphic ugHead = ug.apply(headColor).apply(stroke.onlyThickness());
|
2022-01-19 21:35:53 +00:00
|
|
|
if (linkType.getDecor2().isFill())
|
2022-10-25 20:43:40 +00:00
|
|
|
ugHead = ugHead.apply(color.bg());
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2022-10-25 20:43:40 +00:00
|
|
|
ugHead = ugHead.apply(HColors.none().bg());
|
2023-02-26 18:51:17 +00:00
|
|
|
this.extremity1.drawU(ugHead.apply(magneticForce1));
|
2022-10-25 20:43:40 +00:00
|
|
|
}
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-10-25 20:43:40 +00:00
|
|
|
if (headColor.isTransparent()) {
|
|
|
|
if (this.extremity2 instanceof ExtremityArrow) {
|
|
|
|
final UGraphic ugHead = ug.apply(color).apply(stroke.onlyThickness());
|
2023-02-26 18:51:17 +00:00
|
|
|
((ExtremityArrow) this.extremity2).drawLineIfTransparent(ugHead.apply(magneticForce2));
|
2022-10-25 20:43:40 +00:00
|
|
|
}
|
|
|
|
} else if (this.extremity2 != null) {
|
|
|
|
UGraphic ugHead = ug.apply(headColor).apply(stroke.onlyThickness());
|
|
|
|
if (linkType.getDecor1().isFill())
|
|
|
|
ugHead = ugHead.apply(color.bg());
|
|
|
|
else
|
|
|
|
ugHead = ugHead.apply(HColors.none().bg());
|
2023-02-26 18:51:17 +00:00
|
|
|
this.extremity2.drawU(ugHead.apply(magneticForce2));
|
2019-01-16 18:34:41 +00:00
|
|
|
}
|
2022-10-25 20:43:40 +00:00
|
|
|
|
2019-01-16 18:34:41 +00:00
|
|
|
int i = 0;
|
|
|
|
for (Colors colors : supplementaryColors) {
|
2020-05-17 21:15:50 +00:00
|
|
|
ug.apply(new UTranslate(2 * (i + 1), 2 * (i + 1))).apply(colors.getColor(ColorType.LINE)).draw(todraw);
|
2019-01-16 18:34:41 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
public boolean isInverted() {
|
|
|
|
return link.isInverted();
|
|
|
|
}
|
|
|
|
|
|
|
|
private double getDecorDzeta() {
|
2015-04-07 18:18:37 +00:00
|
|
|
final LinkType linkType = link.getType();
|
|
|
|
final int size1 = linkType.getDecor1().getMargin();
|
|
|
|
final int size2 = linkType.getDecor2().getMargin();
|
2011-08-08 17:48:29 +00:00
|
|
|
return size1 + size2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getHorizontalDzeta(StringBounder stringBounder) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (startUid.equalsId(endUid))
|
2011-08-08 17:48:29 +00:00
|
|
|
return getDecorDzeta();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
final ArithmeticStrategy strategy;
|
2022-01-19 21:35:53 +00:00
|
|
|
if (isHorizontal())
|
2011-08-08 17:48:29 +00:00
|
|
|
strategy = new ArithmeticStrategySum();
|
2022-01-19 21:35:53 +00:00
|
|
|
else
|
2011-08-08 17:48:29 +00:00
|
|
|
return 0;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (hasNoteLabelText())
|
2015-09-28 20:42:17 +00:00
|
|
|
strategy.eat(labelText.calculateDimension(stringBounder).getWidth());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (startTailText != null)
|
2011-08-08 17:48:29 +00:00
|
|
|
strategy.eat(startTailText.calculateDimension(stringBounder).getWidth());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (endHeadText != null)
|
2011-08-08 17:48:29 +00:00
|
|
|
strategy.eat(endHeadText.calculateDimension(stringBounder).getWidth());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
return strategy.getResult() + getDecorDzeta();
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isHorizontal() {
|
|
|
|
return link.getLength() == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getVerticalDzeta(StringBounder stringBounder) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (startUid.equalsId(endUid))
|
2011-08-08 17:48:29 +00:00
|
|
|
return getDecorDzeta();
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (isHorizontal())
|
2011-08-08 17:48:29 +00:00
|
|
|
return 0;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
final ArithmeticStrategy strategy = new ArithmeticStrategySum();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (hasNoteLabelText())
|
2015-09-28 20:42:17 +00:00
|
|
|
strategy.eat(labelText.calculateDimension(stringBounder).getHeight());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (startTailText != null)
|
2011-08-08 17:48:29 +00:00
|
|
|
strategy.eat(startTailText.calculateDimension(stringBounder).getHeight());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (endHeadText != null)
|
2011-08-08 17:48:29 +00:00
|
|
|
strategy.eat(endHeadText.calculateDimension(stringBounder).getHeight());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
return strategy.getResult() + getDecorDzeta();
|
|
|
|
}
|
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
public void manageCollision(Collection<SvekNode> allNodes) {
|
|
|
|
for (SvekNode sh : allNodes) {
|
2011-09-07 20:41:58 +00:00
|
|
|
final Positionable cl = PositionableUtils.addMargin(sh, 8, 8);
|
2022-01-19 21:35:53 +00:00
|
|
|
if (startTailText != null && startTailLabelXY != null && PositionableUtils.intersect(cl, startTailLabelXY))
|
2011-09-07 20:41:58 +00:00
|
|
|
startTailLabelXY = PositionableUtils.moveAwayFrom(cl, startTailLabelXY);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (endHeadText != null && endHeadLabelXY != null && PositionableUtils.intersect(cl, endHeadLabelXY))
|
2011-09-07 20:41:58 +00:00
|
|
|
endHeadLabelXY = PositionableUtils.moveAwayFrom(cl, endHeadLabelXY);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2011-09-07 20:41:58 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-14 18:12:03 +00:00
|
|
|
private XPoint2D avoid2(XPoint2D move, Positionable pos, SvekNode sh) {
|
2011-08-08 17:48:29 +00:00
|
|
|
final Oscillator oscillator = new Oscillator();
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D orig = new XPoint2D(move.x, move.y);
|
2011-08-08 17:48:29 +00:00
|
|
|
while (cut(pos, sh)) {
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D m = oscillator.nextPosition();
|
2022-09-14 18:12:03 +00:00
|
|
|
move = new XPoint2D(orig.x + m.x, orig.y + m.y);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
2022-09-14 18:12:03 +00:00
|
|
|
return move;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
private boolean cut(Positionable pos, SvekNode sh) {
|
2011-08-08 17:48:29 +00:00
|
|
|
return BezierUtils.intersect(pos, sh) || tooClose(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean tooClose(Positionable pos) {
|
|
|
|
final double dist = dotPath.getMinDist(BezierUtils.getCenter(pos));
|
2022-09-12 20:08:34 +00:00
|
|
|
final XDimension2D dim = pos.getSize();
|
2013-12-10 19:36:50 +00:00
|
|
|
// Log.println("dist=" + dist);
|
2011-08-08 17:48:29 +00:00
|
|
|
return dist < (dim.getWidth() / 2 + 2) || dist < (dim.getHeight() / 2 + 2);
|
|
|
|
}
|
|
|
|
|
2011-09-08 10:42:27 +00:00
|
|
|
public void moveSvek(double deltaX, double deltaY) {
|
|
|
|
this.dx += deltaX;
|
|
|
|
this.dy += deltaY;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final DotPath getDotPath() {
|
2022-02-10 18:16:18 +00:00
|
|
|
final DotPath result = dotPath.copy();
|
2011-09-08 10:42:27 +00:00
|
|
|
result.moveSvek(dx, dy);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getLength() {
|
|
|
|
return link.getLength();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setOpale(boolean opale) {
|
|
|
|
this.link.setOpale(opale);
|
|
|
|
this.opale = opale;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isOpale() {
|
|
|
|
return opale;
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public boolean isHorizontalSolitary() {
|
|
|
|
return link.isHorizontalSolitary();
|
|
|
|
}
|
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
public boolean isLinkFromOrTo(Entity group) {
|
2013-12-10 19:36:50 +00:00
|
|
|
return link.getEntity1() == group || link.getEntity2() == group;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasEntryPoint() {
|
|
|
|
return link.hasEntryPoint();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setProjectionCluster(Cluster cluster) {
|
|
|
|
this.projectionCluster = cluster;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isHidden() {
|
|
|
|
return link.isHidden();
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
public boolean sameConnections(SvekLine other) {
|
2013-12-10 19:36:50 +00:00
|
|
|
return link.sameConnections(other.link);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isAutolink() {
|
|
|
|
return link.getEntity1() == link.getEntity2();
|
|
|
|
}
|
2011-09-08 10:42:27 +00:00
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
public XPoint2D getMyPoint(Entity entity) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.getEntity1() == entity)
|
2015-04-07 18:18:37 +00:00
|
|
|
return moveDelta(dotPath.getStartPoint());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
|
|
|
if (link.getEntity2() == entity)
|
2015-04-07 18:18:37 +00:00
|
|
|
return moveDelta(dotPath.getEndPoint());
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
private XPoint2D moveDelta(XPoint2D pt) {
|
|
|
|
return new XPoint2D(pt.getX() + dx, pt.getY() + dy);
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isLink(Link link) {
|
|
|
|
return this.link == link;
|
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
public XPoint2D getStartContactPoint() {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (dotPath == null)
|
|
|
|
return null;
|
2022-09-12 20:08:34 +00:00
|
|
|
final XPoint2D start = dotPath.getStartPoint();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (start == null)
|
2015-04-07 18:18:37 +00:00
|
|
|
return null;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
return new XPoint2D(dx + start.getX(), dy + start.getY());
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
public XPoint2D getEndContactPoint() {
|
|
|
|
final XPoint2D end = dotPath.getEndPoint();
|
2022-01-19 21:35:53 +00:00
|
|
|
if (end == null)
|
2015-04-07 18:18:37 +00:00
|
|
|
return null;
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2022-09-12 20:08:34 +00:00
|
|
|
return new XPoint2D(dx + end.getX(), dy + end.getY());
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
2023-02-06 21:04:53 +00:00
|
|
|
public Entity getOther(Entity entity) {
|
2022-01-19 21:35:53 +00:00
|
|
|
if (link.contains(entity))
|
2015-05-31 18:56:03 +00:00
|
|
|
return link.getOther(entity);
|
2022-01-19 21:35:53 +00:00
|
|
|
|
2015-05-31 18:56:03 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-03-07 12:23:24 +00:00
|
|
|
public StyleBuilder getCurrentStyleBuilder() {
|
|
|
|
return link.getStyleBuilder();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Stereotype getStereotype() {
|
|
|
|
return link.getStereotype();
|
|
|
|
}
|
|
|
|
|
2022-08-26 16:00:28 +00:00
|
|
|
public void moveStartPoint(double dx, double dy) {
|
|
|
|
dotPath.moveStartPoint(dx, dy);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void moveEndPoint(double dx, double dy) {
|
|
|
|
dotPath.moveEndPoint(dx, dy);
|
|
|
|
}
|
|
|
|
|
2021-11-05 05:03:15 +00:00
|
|
|
}
|