This commit is contained in:
Arnaud Roques 2022-01-19 22:35:53 +01:00
parent 402c492b70
commit c623158c6c
11 changed files with 208 additions and 178 deletions

View File

@ -60,11 +60,15 @@ public class EmptyImageBuilder {
private final Color background; private final Color background;
private final StringBounder stringBounder; private final StringBounder stringBounder;
public EmptyImageBuilder(String watermark, double width, double height, Color background, StringBounder stringBounder) { public EmptyImageBuilder(String watermark, double width, double height, Color background,
StringBounder stringBounder) {
this(watermark, (int) width, (int) height, background, stringBounder); this(watermark, (int) width, (int) height, background, stringBounder);
} }
public EmptyImageBuilder(String watermark, int width, int height, Color background, StringBounder stringBounder) { public EmptyImageBuilder(String watermark, int width, int height, Color background, StringBounder stringBounder) {
if (width <= 0 || height <= 0)
throw new IllegalArgumentException("width and height must be positive");
if (width > GraphvizUtils.getenvImageLimit()) { if (width > GraphvizUtils.getenvImageLimit()) {
Log.info("Width too large " + width + ". You should set PLANTUML_LIMIT_SIZE"); Log.info("Width too large " + width + ". You should set PLANTUML_LIMIT_SIZE");
width = GraphvizUtils.getenvImageLimit(); width = GraphvizUtils.getenvImageLimit();
@ -152,7 +156,8 @@ public class EmptyImageBuilder {
return result; return result;
} }
public EmptyImageBuilder(String watermark, int width, int height, Color background, StringBounder stringBounder, double dpiFactor) { public EmptyImageBuilder(String watermark, int width, int height, Color background, StringBounder stringBounder,
double dpiFactor) {
this(watermark, width * dpiFactor, height * dpiFactor, background, stringBounder); this(watermark, width * dpiFactor, height * dpiFactor, background, stringBounder);
if (dpiFactor != 1.0) { if (dpiFactor != 1.0) {
g2d.setTransform(AffineTransform.getScaleInstance(dpiFactor, dpiFactor)); g2d.setTransform(AffineTransform.getScaleInstance(dpiFactor, dpiFactor));

View File

@ -610,7 +610,11 @@ public class SkinParam implements ISkinParam {
} }
public int getDpi() { public int getDpi() {
return getAsInt("dpi", 96); final int defaultValue = 96;
final int dpi = getAsInt("dpi", defaultValue);
if (dpi <= 0)
return defaultValue;
return dpi;
} }
public DotSplines getDotSplines() { public DotSplines getDotSplines() {

View File

@ -66,6 +66,7 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
private final Swimlane swimlane; private final Swimlane swimlane;
private final Swimlanes swimlanes; private final Swimlanes swimlanes;
private Swimlane swimlaneOut; private Swimlane swimlaneOut;
private Swimlane swimlaneBackward;
private BoxStyle boxStyle; private BoxStyle boxStyle;
private boolean killed = false; private boolean killed = false;
private final BoxStyle boxStyleIn; private final BoxStyle boxStyleIn;
@ -107,10 +108,10 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
return false; return false;
} }
public void setBackward(Display label, Swimlane swimlaneOut, BoxStyle boxStyle, LinkRendering incoming1, public void setBackward(Display label, Swimlane swimlaneBackward, BoxStyle boxStyle, LinkRendering incoming1,
LinkRendering incoming2) { LinkRendering incoming2) {
this.backward = label; this.backward = label;
this.swimlaneOut = swimlaneOut; this.swimlaneBackward = swimlaneBackward;
this.boxStyle = boxStyle; this.boxStyle = boxStyle;
this.incoming1 = incoming1; this.incoming1 = incoming1;
this.incoming2 = incoming2; this.incoming2 = incoming2;
@ -162,9 +163,9 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
if (Display.isNull(backward)) if (Display.isNull(backward))
return null; return null;
Ftile result = factory.activity(backward, swimlaneOut, boxStyle, Colors.empty(), null); Ftile result = factory.activity(backward, swimlaneBackward, boxStyle, Colors.empty(), null);
if (backwardNotes.size() > 0) if (backwardNotes.size() > 0)
result = factory.addNote(result, swimlaneOut, backwardNotes); result = factory.addNote(result, swimlaneBackward, backwardNotes);
return result; return result;
} }

View File

@ -112,6 +112,8 @@ class FtileRepeat extends AbstractFtile {
final Set<Swimlane> result = new HashSet<>(repeat.getSwimlanes()); final Set<Swimlane> result = new HashSet<>(repeat.getSwimlanes());
result.addAll(diamond1.getSwimlanes()); result.addAll(diamond1.getSwimlanes());
result.addAll(diamond2.getSwimlanes()); result.addAll(diamond2.getSwimlanes());
if (backward != null)
result.addAll(backward.getSwimlanes());
return Collections.unmodifiableSet(result); return Collections.unmodifiableSet(result);
} }
@ -132,20 +134,20 @@ class FtileRepeat extends AbstractFtile {
final Ftile diamond1; final Ftile diamond1;
// assert swimlane == repeat.getSwimlaneIn(); // assert swimlane == repeat.getSwimlaneIn();
if (entry == null) { if (entry == null)
diamond1 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, repeat.getSwimlaneIn()); diamond1 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, repeat.getSwimlaneIn());
} else { else
diamond1 = entry; diamond1 = entry;
}
final FtileRepeat result; final FtileRepeat result;
if (conditionStyle == ConditionStyle.INSIDE_HEXAGON) { if (conditionStyle == ConditionStyle.INSIDE_HEXAGON) {
final Ftile diamond2; final Ftile diamond2;
if (noOut && Display.isNull(test)) { if (noOut && Display.isNull(test))
diamond2 = new FtileEmpty(repeat.skinParam()); diamond2 = new FtileEmpty(repeat.skinParam());
} else { else
diamond2 = new FtileDiamondInside(tbTest, repeat.skinParam(), diamondColor, borderColor, swimlaneOut) diamond2 = new FtileDiamondInside(tbTest, repeat.skinParam(), diamondColor, borderColor, swimlaneOut)
.withEast(yesTb).withSouth(outTb); .withEast(yesTb).withSouth(outTb);
}
result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward); result = new FtileRepeat(repeat, diamond1, diamond2, TextBlockUtils.empty(0, 0), backward);
} else if (conditionStyle == ConditionStyle.EMPTY_DIAMOND) { } else if (conditionStyle == ConditionStyle.EMPTY_DIAMOND) {
final Ftile diamond2 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, swimlane) final Ftile diamond2 = new FtileDiamond(repeat.skinParam(), diamondColor, borderColor, swimlane)
@ -254,9 +256,8 @@ class FtileRepeat extends AbstractFtile {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder(); final StringBounder stringBounder = ug.getStringBounder();
if (getFtile1().calculateDimension(stringBounder).hasPointOut() == false) { if (getFtile1().calculateDimension(stringBounder).hasPointOut() == false)
return; return;
}
final Snake snake = Snake.create(arrowColor, Arrows.asToDown()).withLabel(tbout, final Snake snake = Snake.create(arrowColor, Arrows.asToDown()).withLabel(tbout,
arrowHorizontalAlignment()); arrowHorizontalAlignment());
@ -269,9 +270,9 @@ class FtileRepeat extends AbstractFtile {
@Override @Override
public void drawTranslate(UGraphic ug, UTranslate translate1, UTranslate translate2) { public void drawTranslate(UGraphic ug, UTranslate translate1, UTranslate translate2) {
final StringBounder stringBounder = ug.getStringBounder(); final StringBounder stringBounder = ug.getStringBounder();
if (getFtile1().calculateDimension(stringBounder).hasPointOut() == false) { if (getFtile1().calculateDimension(stringBounder).hasPointOut() == false)
return; return;
}
final Snake snake = Snake.create(arrowColor); final Snake snake = Snake.create(arrowColor);
final Point2D mp1a = translate1.getTranslated(getP1(stringBounder)); final Point2D mp1a = translate1.getTranslated(getP1(stringBounder));
final Point2D mp2b = translate2.getTranslated(getP2(stringBounder)); final Point2D mp2b = translate2.getTranslated(getP2(stringBounder));
@ -353,7 +354,7 @@ class FtileRepeat extends AbstractFtile {
} }
class ConnectionBackBackward1 extends AbstractConnection { class ConnectionBackBackward1 extends AbstractConnection implements ConnectionTranslatable {
private final Rainbow arrowColor; private final Rainbow arrowColor;
private final TextBlock tbback; private final TextBlock tbback;
@ -392,6 +393,30 @@ class FtileRepeat extends AbstractFtile {
ug.draw(snake); ug.draw(snake);
} }
@Override
public void drawTranslate(UGraphic ug, UTranslate translate1, UTranslate translate2) {
final StringBounder stringBounder = ug.getStringBounder();
Point2D p1 = getP1(stringBounder);
Point2D p2 = getP2(stringBounder);
p1 = translate1.getTranslated(p1);
p2 = translate2.getTranslated(p2);
final Dimension2D dimDiamond2 = diamond2.calculateDimension(stringBounder);
final double x1 = p1.getX() + dimDiamond2.getWidth();
final double y1 = p1.getY() + dimDiamond2.getHeight() / 2;
final double x2 = p2.getX();
final double y2 = p2.getY();
final Snake snake = Snake.create(arrowColor, Arrows.asToUp()).withLabel(tbback, arrowHorizontalAlignment());
snake.addPoint(x1, y1);
snake.addPoint(x2, y1);
snake.addPoint(x2, y2);
ug.draw(snake);
}
} }
class ConnectionBackBackward2 extends AbstractConnection implements ConnectionTranslatable { class ConnectionBackBackward2 extends AbstractConnection implements ConnectionTranslatable {
@ -545,9 +570,8 @@ class FtileRepeat extends AbstractFtile {
ug.apply(getTranslateForRepeat(stringBounder)).draw(repeat); ug.apply(getTranslateForRepeat(stringBounder)).draw(repeat);
ug.apply(getTranslateDiamond1(stringBounder)).draw(diamond1); ug.apply(getTranslateDiamond1(stringBounder)).draw(diamond1);
ug.apply(getTranslateDiamond2(stringBounder)).draw(diamond2); ug.apply(getTranslateDiamond2(stringBounder)).draw(diamond2);
if (backward != null) { if (backward != null)
ug.apply(getTranslateBackward(stringBounder)).draw(backward); ug.apply(getTranslateBackward(stringBounder)).draw(backward);
}
} }
@ -566,9 +590,9 @@ class FtileRepeat extends AbstractFtile {
double width = getLeft(stringBounder) + getRight(stringBounder); double width = getLeft(stringBounder) + getRight(stringBounder);
width = Math.max(width, w + 2 * Hexagon.hexagonHalfSize); width = Math.max(width, w + 2 * Hexagon.hexagonHalfSize);
if (backward != null) { if (backward != null)
width += backward.calculateDimension(stringBounder).getWidth(); width += backward.calculateDimension(stringBounder).getWidth();
}
final double height = dimDiamond1.getHeight() + dimRepeat.getHeight() + dimDiamond2.getHeight() final double height = dimDiamond1.getHeight() + dimRepeat.getHeight() + dimDiamond2.getHeight()
+ 8 * Hexagon.hexagonHalfSize; + 8 * Hexagon.hexagonHalfSize;
return new Dimension2DDouble(width + 2 * Hexagon.hexagonHalfSize, height); return new Dimension2DDouble(width + 2 * Hexagon.hexagonHalfSize, height);
@ -577,12 +601,12 @@ class FtileRepeat extends AbstractFtile {
@Override @Override
public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) { public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) {
if (child == repeat) { if (child == repeat)
return getTranslateForRepeat(stringBounder); return getTranslateForRepeat(stringBounder);
}
if (child == diamond1) { if (child == diamond1)
return getTranslateDiamond1(stringBounder); return getTranslateDiamond1(stringBounder);
}
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -93,12 +93,12 @@ public class Neighborhood {
final SvekLine line = bibliotekon.getLine(link); final SvekLine line = bibliotekon.getLine(link);
final Point2D contact = link.getEntity1() == leaf ? line.getStartContactPoint() : line.getEndContactPoint(); final Point2D contact = link.getEntity1() == leaf ? line.getStartContactPoint() : line.getEndContactPoint();
if (contact == null) { if (contact == null) {
assert false; // assert false;
continue; continue;
} }
final Point2D inter = intersection(rect, center, contact); final Point2D inter = intersection(rect, center, contact);
if (inter == null) { if (inter == null) {
assert false; // assert false;
continue; continue;
} }
drawLine(ug, inter, contact); drawLine(ug, inter, contact);

View File

@ -219,7 +219,10 @@ public class Emoji {
final HColorSimple result = (HColorSimple) HColorSet.instance().getColorOrWhite(code); final HColorSimple result = (HColorSimple) HColorSet.instance().getColorOrWhite(code);
if (colorForMonochrome == null) if (colorForMonochrome == null)
return result; return result;
return result.asMonochrome((HColorSimple) colorForMonochrome, this.minGray, this.maxGray); final HColorSimple color = (HColorSimple) colorForMonochrome;
if (color.isGray())
return result.asMonochrome();
return result.asMonochrome(color, this.minGray, this.maxGray);
} }
private void drawCircle(UGraphicWithScale ugs, String s, HColor colorForMonochrome) { private void drawCircle(UGraphicWithScale ugs, String s, HColor colorForMonochrome) {

View File

@ -55,7 +55,9 @@ public class EntityImageProtected extends AbstractTextBlock implements IEntityIm
private final Neighborhood neighborhood; private final Neighborhood neighborhood;
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) { public Rectangle2D getInnerPosition(String member, StringBounder stringBounder, InnerStrategy strategy) {
throw new UnsupportedOperationException(); final Rectangle2D result = orig.getInnerPosition(member, stringBounder, strategy);
return new Rectangle2D.Double(result.getMinX() + border, result.getMinY() + border, result.getWidth(),
result.getHeight());
} }
public EntityImageProtected(IEntityImage orig, double border, Neighborhood neighborhood, Bibliotekon bibliotekon) { public EntityImageProtected(IEntityImage orig, double border, Neighborhood neighborhood, Bibliotekon bibliotekon) {

View File

@ -156,9 +156,9 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public Direction getArrowDirection() { public Direction getArrowDirection() {
if (getLinkArrow() == LinkArrow.BACKWARD) { if (getLinkArrow() == LinkArrow.BACKWARD)
return getArrowDirectionInternal().getInv(); return getArrowDirectionInternal().getInv();
}
return getArrowDirectionInternal(); return getArrowDirectionInternal();
} }
@ -170,19 +170,19 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
final Point2D start = dotPath.getStartPoint(); final Point2D start = dotPath.getStartPoint();
final Point2D end = dotPath.getEndPoint(); final Point2D end = dotPath.getEndPoint();
final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY()); final double ang = Math.atan2(end.getX() - start.getX(), end.getY() - start.getY());
if (ang > -Math.PI / 4 && ang < Math.PI / 4) { if (ang > -Math.PI / 4 && ang < Math.PI / 4)
return Direction.DOWN; return Direction.DOWN;
}
if (ang > Math.PI * 3 / 4 || ang < -Math.PI * 3 / 4) { if (ang > Math.PI * 3 / 4 || ang < -Math.PI * 3 / 4)
return Direction.UP; return Direction.UP;
}
return end.getX() > start.getX() ? Direction.RIGHT : Direction.LEFT; return end.getX() > start.getX() ? Direction.RIGHT : Direction.LEFT;
} }
public double getArrowDirection2() { public double getArrowDirection2() {
if (getLinkArrow() == LinkArrow.BACKWARD) { if (getLinkArrow() == LinkArrow.BACKWARD)
return Math.PI + getArrowDirectionInternal2(); return Math.PI + getArrowDirectionInternal2();
}
return getArrowDirectionInternal2(); return getArrowDirectionInternal2();
} }
@ -198,11 +198,10 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
private Cluster getCluster2(Bibliotekon bibliotekon, IEntity entityMutable) { private Cluster getCluster2(Bibliotekon bibliotekon, IEntity entityMutable) {
for (Cluster cl : bibliotekon.allCluster()) { for (Cluster cl : bibliotekon.allCluster())
if (cl.getGroups().contains(entityMutable)) { if (cl.getGroups().contains(entityMutable))
return cl; return cl;
}
}
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -217,13 +216,12 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
this.endUid = link.getEntityPort2(bibliotekon); this.endUid = link.getEntityPort2(bibliotekon);
Cluster ltail = null; Cluster ltail = null;
if (startUid.startsWith(Cluster.CENTER_ID)) { if (startUid.startsWith(Cluster.CENTER_ID))
ltail = getCluster2(bibliotekon, link.getEntity1()); ltail = getCluster2(bibliotekon, link.getEntity1());
}
Cluster lhead = null; Cluster lhead = null;
if (endUid.startsWith(Cluster.CENTER_ID)) { if (endUid.startsWith(Cluster.CENTER_ID))
lhead = getCluster2(bibliotekon, link.getEntity2()); lhead = getCluster2(bibliotekon, link.getEntity2());
}
if (link.getColors() != null) { if (link.getColors() != null) {
skinParam = link.getColors().mute(skinParam); skinParam = link.getColors().mute(skinParam);
@ -232,9 +230,9 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
this.backgroundColor = skinParam.getBackgroundColor(); this.backgroundColor = skinParam.getBackgroundColor();
this.defaultThickness = skinParam.getThickness(LineParam.arrow, null); this.defaultThickness = skinParam.getThickness(LineParam.arrow, null);
this.arrowLollipopColor = skinParam.getHtmlColor(ColorParam.arrowLollipop, null, false); this.arrowLollipopColor = skinParam.getHtmlColor(ColorParam.arrowLollipop, null, false);
if (arrowLollipopColor == null) { if (arrowLollipopColor == null)
this.arrowLollipopColor = backgroundColor; this.arrowLollipopColor = backgroundColor;
}
this.pragma = pragma; this.pragma = pragma;
this.bibliotekon = bibliotekon; this.bibliotekon = bibliotekon;
this.stringBounder = stringBounder; this.stringBounder = stringBounder;
@ -249,22 +247,22 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
TextBlock labelOnly; TextBlock labelOnly;
if (Display.isNull(link.getLabel())) { if (Display.isNull(link.getLabel())) {
labelOnly = TextBlockUtils.EMPTY_TEXT_BLOCK; labelOnly = TextBlockUtils.EMPTY_TEXT_BLOCK;
if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL) { if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL)
labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font); labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font);
}
} else { } else {
final HorizontalAlignment alignment = getMessageTextAlignment(link.getUmlDiagramType(), skinParam); final HorizontalAlignment alignment = getMessageTextAlignment(link.getUmlDiagramType(), skinParam);
final boolean hasSeveralGuideLines = link.getLabel().hasSeveralGuideLines(); final boolean hasSeveralGuideLines = link.getLabel().hasSeveralGuideLines();
final TextBlock block; final TextBlock block;
if (hasSeveralGuideLines) { if (hasSeveralGuideLines)
block = StringWithArrow.addSeveralMagicArrows(link.getLabel(), this, font, alignment, skinParam); block = StringWithArrow.addSeveralMagicArrows(link.getLabel(), this, font, alignment, skinParam);
} else { else
block = link.getLabel().create9(font, alignment, skinParam, skinParam.maxMessageSize()); block = link.getLabel().create9(font, alignment, skinParam, skinParam.maxMessageSize());
}
labelOnly = addVisibilityModifier(block, link, skinParam); labelOnly = addVisibilityModifier(block, link, skinParam);
if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL && hasSeveralGuideLines == false) { if (getLinkArrow() != LinkArrow.NONE_OR_SEVERAL && hasSeveralGuideLines == false)
labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font); labelOnly = StringWithArrow.addMagicArrow(labelOnly, this, font);
}
} }
final TextBlock noteOnly; final TextBlock noteOnly;
@ -273,40 +271,36 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} else { } else {
noteOnly = new EntityImageNoteLink(link.getNote(), link.getNoteColors(), skinParam, link.getStyleBuilder()); noteOnly = new EntityImageNoteLink(link.getNote(), link.getNoteColors(), skinParam, link.getStyleBuilder());
if (link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED if (link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED
|| link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_PRINTED_FULL) { || link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_PRINTED_FULL)
divideLabelWidthByTwo = true; divideLabelWidthByTwo = true;
}
} }
if (link.getNotePosition() == Position.LEFT) { if (link.getNotePosition() == Position.LEFT)
labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER); labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER);
} else if (link.getNotePosition() == Position.RIGHT) { else if (link.getNotePosition() == Position.RIGHT)
labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER); labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER);
} else if (link.getNotePosition() == Position.TOP) { else if (link.getNotePosition() == Position.TOP)
labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER); labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER);
} else { else
labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER); labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER);
}
if (link.getQualifier1() == null) { if (link.getQualifier1() == null)
startTailText = null; startTailText = null;
} else { else
startTailText = Display.getWithNewlines(link.getQualifier1()).create(font, HorizontalAlignment.CENTER, startTailText = Display.getWithNewlines(link.getQualifier1()).create(font, HorizontalAlignment.CENTER,
skinParam); skinParam);
}
if (link.getQualifier2() == null) { if (link.getQualifier2() == null)
endHeadText = null; endHeadText = null;
} else { else
endHeadText = Display.getWithNewlines(link.getQualifier2()).create(font, HorizontalAlignment.CENTER, endHeadText = Display.getWithNewlines(link.getQualifier2()).create(font, HorizontalAlignment.CENTER,
skinParam); skinParam);
}
if (link.getType().getMiddleDecor() == LinkMiddleDecor.NONE) { if (link.getType().getMiddleDecor() == LinkMiddleDecor.NONE)
this.labelShield = 0; this.labelShield = 0;
} else { else
this.labelShield = 7; this.labelShield = 7;
}
} }
@ -324,9 +318,9 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) { private HorizontalAlignment getMessageTextAlignment(UmlDiagramType umlDiagramType, ISkinParam skinParam) {
if (umlDiagramType == UmlDiagramType.STATE) { if (umlDiagramType == UmlDiagramType.STATE)
return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false, null); return skinParam.getHorizontalAlignment(AlignmentParam.stateMessageAlignment, null, false, null);
}
return skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER); return skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER);
} }
@ -352,15 +346,15 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
sb.append("["); sb.append("[");
final LinkType linkType = link.getTypePatchCluster(); final LinkType linkType = link.getTypePatchCluster();
String decoration = linkType.getSpecificDecorationSvek(); String decoration = linkType.getSpecificDecorationSvek();
if (decoration.length() > 0 && decoration.endsWith(",") == false) { if (decoration.length() > 0 && decoration.endsWith(",") == false)
decoration += ","; decoration += ",";
}
sb.append(decoration); sb.append(decoration);
int length = link.getLength(); int length = link.getLength();
if (graphvizVersion.ignoreHorizontalLinks() && length == 1) { if (graphvizVersion.ignoreHorizontalLinks() && length == 1)
length = 2; length = 2;
}
if (useRankSame) { if (useRankSame) {
if (pragma.horizontalLineBetweenDifferentPackageAllowed() || link.isInvis() || length != 1) { if (pragma.horizontalLineBetweenDifferentPackageAllowed() || link.isInvis() || length != 1) {
// if (graphvizVersion.isJs() == false) { // if (graphvizVersion.isJs() == false) {
@ -406,22 +400,20 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
sb.append("style=invis"); sb.append("style=invis");
} }
if (link.isConstraint() == false || link.hasTwoEntryPointsSameContainer()) { if (link.isConstraint() == false || link.hasTwoEntryPointsSameContainer())
sb.append(",constraint=false"); sb.append(",constraint=false");
}
if (link.getSametail() != null) { if (link.getSametail() != null)
sb.append(",sametail=" + link.getSametail()); sb.append(",sametail=" + link.getSametail());
}
sb.append("];"); sb.append("];");
SvekUtils.println(sb); SvekUtils.println(sb);
} }
private Dimension2D eventuallyDivideByTwo(Dimension2D dim) { private Dimension2D eventuallyDivideByTwo(Dimension2D dim) {
if (divideLabelWidthByTwo) { if (divideLabelWidthByTwo)
return new Dimension2DDouble(dim.getWidth() / 2, dim.getHeight()); return new Dimension2DDouble(dim.getWidth() / 2, dim.getHeight());
}
return dim; return dim;
} }
@ -474,24 +466,24 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
// System.err.println("angle=" + angle * 180 / Math.PI); // System.err.println("angle=" + angle * 180 / Math.PI);
return extremityFactory.createUDrawable(center, angle, null); return extremityFactory.createUDrawable(center, angle, null);
} }
if (decor == LinkDecor.EXTENDS) { if (decor == LinkDecor.EXTENDS)
return new ExtremityFactoryExtends(backgroundColor).createUDrawable(center, angle, null); return new ExtremityFactoryExtends(backgroundColor).createUDrawable(center, angle, null);
}
return null; return null;
} }
if (extremityFactory != null) { if (extremityFactory != null) {
final List<Point2D.Double> points = pointListIterator.next(); final List<Point2D.Double> points = pointListIterator.next();
if (points.size() == 0) { if (points.size() == 0)
return extremityFactory.createUDrawable(center, angle, null); return extremityFactory.createUDrawable(center, angle, null);
}
final Point2D p0 = points.get(0); final Point2D p0 = points.get(0);
final Point2D p1 = points.get(1); final Point2D p1 = points.get(1);
final Point2D p2 = points.get(2); final Point2D p2 = points.get(2);
Side side = null; Side side = null;
if (nodeContact != null) { if (nodeContact != null)
side = nodeContact.getClusterPosition().getClosestSide(p1); side = nodeContact.getClusterPosition().getClosestSide(p1);
}
return extremityFactory.createUDrawable(p0, p1, p2, side); return extremityFactory.createUDrawable(p0, p1, p2, side);
} else if (decor == LinkDecor.NONE) { } else if (decor == LinkDecor.NONE) {
final UPolygon sh = new UPolygon(pointListIterator.cloneMe().next()); final UPolygon sh = new UPolygon(pointListIterator.cloneMe().next());
@ -514,9 +506,8 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public void solveLine(SvgResult fullSvg) { public void solveLine(SvgResult fullSvg) {
if (this.link.isInvis()) { if (this.link.isInvis())
return; return;
}
int idx = fullSvg.getIndexFromColor(this.lineColor); int idx = fullSvg.getIndexFromColor(this.lineColor);
if (idx == -1) { if (idx == -1) {
@ -524,15 +515,15 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
// throw new IllegalStateException(); // throw new IllegalStateException();
} }
idx = fullSvg.indexOf("d=\"", idx); idx = fullSvg.indexOf("d=\"", idx);
if (idx == -1) { if (idx == -1)
throw new IllegalStateException(); throw new IllegalStateException();
}
final int end = fullSvg.indexOf("\"", idx + 3); final int end = fullSvg.indexOf("\"", idx + 3);
final SvgResult path = fullSvg.substring(idx + 3, end); final SvgResult path = fullSvg.substring(idx + 3, end);
if (DotPath.isPathConsistent(path.getSvg()) == false) { if (DotPath.isPathConsistent(path.getSvg()) == false)
return; return;
}
dotPath = new DotPath(path); dotPath = new DotPath(path);
if (projectionCluster != null) { if (projectionCluster != null) {
@ -557,12 +548,11 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(), this.extremity2 = getExtremity(linkType.getDecor1(), pointListIterator, dotPath.getEndPoint(),
dotPath.getEndAngle(), lhead, bibliotekon.getNode(link.getEntity2())); dotPath.getEndAngle(), lhead, bibliotekon.getNode(link.getEntity2()));
if (link.getEntity1().getLeafType() == LeafType.LOLLIPOP_HALF) { if (link.getEntity1().getLeafType() == LeafType.LOLLIPOP_HALF)
bibliotekon.getNode(link.getEntity1()).addImpact(dotPath.getStartAngle() + Math.PI); bibliotekon.getNode(link.getEntity1()).addImpact(dotPath.getStartAngle() + Math.PI);
}
if (link.getEntity2().getLeafType() == LeafType.LOLLIPOP_HALF) { if (link.getEntity2().getLeafType() == LeafType.LOLLIPOP_HALF)
bibliotekon.getNode(link.getEntity2()).addImpact(dotPath.getEndAngle()); bibliotekon.getNode(link.getEntity2()).addImpact(dotPath.getEndAngle());
}
if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) { if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) {
final Point2D p1 = ((Extremity) extremity1).somePoint(); final Point2D p1 = ((Extremity) extremity1).somePoint();
@ -610,9 +600,9 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
} }
if (isOpalisable() == false) { if (isOpalisable() == false)
setOpale(false); setOpale(false);
}
} }
private boolean isOpalisable() { private boolean isOpalisable() {
@ -621,26 +611,25 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
private Point2D.Double getXY(SvgResult svgResult, int color) { private Point2D.Double getXY(SvgResult svgResult, int color) {
final int idx = svgResult.getIndexFromColor(color); final int idx = svgResult.getIndexFromColor(color);
if (idx == -1) { if (idx == -1)
return null; return null;
}
return SvekUtils.getMinXY(svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS)); return SvekUtils.getMinXY(svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS));
} }
public void drawU(UGraphic ug, UStroke suggestedStroke, HColor color, Set<String> ids) { public void drawU(UGraphic ug, UStroke suggestedStroke, HColor color, Set<String> ids) {
if (opale) { if (opale)
return; return;
}
ug.draw(link.commentForSvg()); ug.draw(link.commentForSvg());
ug.startGroup(UGroupType.CLASS, ug.startGroup(UGroupType.CLASS,
"link " + link.getEntity1().getCode() + " " + link.getEntity2().getCode() + " selected"); "link " + link.getEntity1().getCode() + " " + link.getEntity2().getCode() + " selected");
double x = 0; double x = 0;
double y = 0; double y = 0;
final Url url = link.getUrl(); final Url url = link.getUrl();
if (url != null) { if (url != null)
ug.startUrl(url); ug.startUrl(url);
}
if (link.isAutoLinkOfAGroup()) { if (link.isAutoLinkOfAGroup()) {
final Cluster cl = bibliotekon.getCluster((IGroup) link.getEntity1()); final Cluster cl = bibliotekon.getCluster((IGroup) link.getEntity1());
@ -653,28 +642,24 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
x += dx; x += dx;
y += dy; y += dy;
if (link.isInvis()) { if (link.isInvis())
return; return;
}
if (this.link.getColors() != null) { if (this.link.getColors() != null) {
final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE); final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE);
if (newColor != null) { if (newColor != null)
color = newColor; color = newColor;
} } else if (this.link.getSpecificColor() != null)
} else if (this.link.getSpecificColor() != null) {
color = this.link.getSpecificColor(); color = this.link.getSpecificColor();
}
ug = ug.apply(new HColorNone().bg()).apply(color); ug = ug.apply(new HColorNone().bg()).apply(color);
final LinkType linkType = link.getType(); final LinkType linkType = link.getType();
UStroke stroke = suggestedStroke == null || linkType.getStyle().isNormal() == false UStroke stroke = suggestedStroke == null || linkType.getStyle().isNormal() == false
? linkType.getStroke3(defaultThickness) ? linkType.getStroke3(defaultThickness)
: suggestedStroke; : suggestedStroke;
if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null) { if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null)
stroke = link.getColors().getSpecificLineStroke(); stroke = link.getColors().getSpecificLineStroke();
}
ug = ug.apply(stroke); ug = ug.apply(stroke);
// double moveEndY = 0; // double moveEndY = 0;
@ -697,13 +682,12 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) { if (extremity1 instanceof Extremity && extremity2 instanceof Extremity) {
// http://forum.plantuml.net/9421/arrow-inversion-with-skinparam-linetype-ortho-missing-arrow // http://forum.plantuml.net/9421/arrow-inversion-with-skinparam-linetype-ortho-missing-arrow
final Point2D p1 = ((Extremity) extremity1).isTooSmallSoGiveThePointCloserToThisOne(todraw.getStartPoint()); final Point2D p1 = ((Extremity) extremity1).isTooSmallSoGiveThePointCloserToThisOne(todraw.getStartPoint());
if (p1 != null) { if (p1 != null)
todraw.forceStartPoint(p1.getX(), p1.getY()); todraw.forceStartPoint(p1.getX(), p1.getY());
}
final Point2D p2 = ((Extremity) extremity2).isTooSmallSoGiveThePointCloserToThisOne(todraw.getEndPoint()); final Point2D p2 = ((Extremity) extremity2).isTooSmallSoGiveThePointCloserToThisOne(todraw.getEndPoint());
if (p2 != null) { if (p2 != null)
todraw.forceEndPoint(p2.getX(), p2.getY()); todraw.forceEndPoint(p2.getX(), p2.getY());
}
} }
@ -716,19 +700,17 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
ug = ug.apply(new UStroke()).apply(color); ug = ug.apply(new UStroke()).apply(color);
if (hasNoteLabelText() && this.labelXY != null if (hasNoteLabelText() && this.labelXY != null
&& link.getNoteLinkStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED) { && link.getNoteLinkStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED)
this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX() + labelShield, this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX() + labelShield,
y + this.labelXY.getPosition().getY() + labelShield))); y + this.labelXY.getPosition().getY() + labelShield)));
}
if (this.startTailText != null && this.startTailLabelXY != null if (this.startTailText != null && this.startTailLabelXY != null && this.startTailLabelXY.getPosition() != null)
&& this.startTailLabelXY.getPosition() != null) {
this.startTailText.drawU(ug.apply(new UTranslate(x + this.startTailLabelXY.getPosition().getX(), this.startTailText.drawU(ug.apply(new UTranslate(x + this.startTailLabelXY.getPosition().getX(),
y + this.startTailLabelXY.getPosition().getY()))); y + this.startTailLabelXY.getPosition().getY())));
}
if (this.endHeadText != null && this.endHeadLabelXY != null && this.endHeadLabelXY.getPosition() != null) { if (this.endHeadText != null && this.endHeadLabelXY != null && this.endHeadLabelXY.getPosition() != null)
this.endHeadText.drawU(ug.apply(new UTranslate(x + this.endHeadLabelXY.getPosition().getX(), this.endHeadText.drawU(ug.apply(new UTranslate(x + this.endHeadLabelXY.getPosition().getX(),
y + this.endHeadLabelXY.getPosition().getY()))); y + this.endHeadLabelXY.getPosition().getY())));
}
if (linkType.getMiddleDecor() != LinkMiddleDecor.NONE) { if (linkType.getMiddleDecor() != LinkMiddleDecor.NONE) {
final PointAndAngle middle = dotPath.getMiddle(); final PointAndAngle middle = dotPath.getMiddle();
@ -739,9 +721,8 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
mi.drawU(ug.apply(new UTranslate(x + middle.getX(), y + middle.getY()))); mi.drawU(ug.apply(new UTranslate(x + middle.getX(), y + middle.getY())));
} }
if (url != null) { if (url != null)
ug.closeUrl(); ug.closeUrl();
}
if (link.getLinkConstraint() != null) { if (link.getLinkConstraint() != null) {
final double xConstraint = x + this.labelXY.getPosition().getX(); final double xConstraint = x + this.labelXY.getPosition().getX();
@ -789,9 +770,9 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
while (true) { while (true) {
final String candidate = comment + "-" + i; final String candidate = comment + "-" + i;
changed = ids.add(candidate); changed = ids.add(candidate);
if (changed) { if (changed)
return candidate; return candidate;
}
i++; i++;
} }
} }
@ -803,21 +784,21 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
if (this.extremity2 != null) { if (this.extremity2 != null) {
UGraphic ug2 = ug.apply(color).apply(stroke.onlyThickness()); UGraphic ug2 = ug.apply(color).apply(stroke.onlyThickness());
if (linkType.getDecor1().isFill()) { if (linkType.getDecor1().isFill())
ug2 = ug2.apply(color.bg()); ug2 = ug2.apply(color.bg());
} else { else
ug2 = ug2.apply(new HColorNone().bg()); ug2 = ug2.apply(new HColorNone().bg());
}
// System.err.println("Line::draw EXTREMITY1"); // System.err.println("Line::draw EXTREMITY1");
this.extremity2.drawU(ug2); this.extremity2.drawU(ug2);
} }
if (this.extremity1 != null) { if (this.extremity1 != null) {
UGraphic ug2 = ug.apply(color).apply(stroke.onlyThickness()); UGraphic ug2 = ug.apply(color).apply(stroke.onlyThickness());
if (linkType.getDecor2().isFill()) { if (linkType.getDecor2().isFill())
ug2 = ug2.apply(color.bg()); ug2 = ug2.apply(color.bg());
} else { else
ug2 = ug2.apply(new HColorNone().bg()); ug2 = ug2.apply(new HColorNone().bg());
}
// System.err.println("Line::draw EXTREMITY2"); // System.err.println("Line::draw EXTREMITY2");
this.extremity1.drawU(ug2); this.extremity1.drawU(ug2);
} }
@ -840,24 +821,24 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public double getHorizontalDzeta(StringBounder stringBounder) { public double getHorizontalDzeta(StringBounder stringBounder) {
if (startUid.equalsId(endUid)) { if (startUid.equalsId(endUid))
return getDecorDzeta(); return getDecorDzeta();
}
final ArithmeticStrategy strategy; final ArithmeticStrategy strategy;
if (isHorizontal()) { if (isHorizontal())
strategy = new ArithmeticStrategySum(); strategy = new ArithmeticStrategySum();
} else { else
return 0; return 0;
}
if (hasNoteLabelText()) { if (hasNoteLabelText())
strategy.eat(labelText.calculateDimension(stringBounder).getWidth()); strategy.eat(labelText.calculateDimension(stringBounder).getWidth());
}
if (startTailText != null) { if (startTailText != null)
strategy.eat(startTailText.calculateDimension(stringBounder).getWidth()); strategy.eat(startTailText.calculateDimension(stringBounder).getWidth());
}
if (endHeadText != null) { if (endHeadText != null)
strategy.eat(endHeadText.calculateDimension(stringBounder).getWidth()); strategy.eat(endHeadText.calculateDimension(stringBounder).getWidth());
}
return strategy.getResult() + getDecorDzeta(); return strategy.getResult() + getDecorDzeta();
} }
@ -866,36 +847,34 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public double getVerticalDzeta(StringBounder stringBounder) { public double getVerticalDzeta(StringBounder stringBounder) {
if (startUid.equalsId(endUid)) { if (startUid.equalsId(endUid))
return getDecorDzeta(); return getDecorDzeta();
}
if (isHorizontal()) { if (isHorizontal())
return 0; return 0;
}
final ArithmeticStrategy strategy = new ArithmeticStrategySum(); final ArithmeticStrategy strategy = new ArithmeticStrategySum();
if (hasNoteLabelText()) { if (hasNoteLabelText())
strategy.eat(labelText.calculateDimension(stringBounder).getHeight()); strategy.eat(labelText.calculateDimension(stringBounder).getHeight());
}
if (startTailText != null) { if (startTailText != null)
strategy.eat(startTailText.calculateDimension(stringBounder).getHeight()); strategy.eat(startTailText.calculateDimension(stringBounder).getHeight());
}
if (endHeadText != null) { if (endHeadText != null)
strategy.eat(endHeadText.calculateDimension(stringBounder).getHeight()); strategy.eat(endHeadText.calculateDimension(stringBounder).getHeight());
}
return strategy.getResult() + getDecorDzeta(); return strategy.getResult() + getDecorDzeta();
} }
public void manageCollision(Collection<SvekNode> allNodes) { public void manageCollision(Collection<SvekNode> allNodes) {
for (SvekNode sh : allNodes) { for (SvekNode sh : allNodes) {
final Positionable cl = PositionableUtils.addMargin(sh, 8, 8); final Positionable cl = PositionableUtils.addMargin(sh, 8, 8);
if (startTailText != null && startTailLabelXY != null if (startTailText != null && startTailLabelXY != null && PositionableUtils.intersect(cl, startTailLabelXY))
&& PositionableUtils.intersect(cl, startTailLabelXY)) {
startTailLabelXY = PositionableUtils.moveAwayFrom(cl, startTailLabelXY); startTailLabelXY = PositionableUtils.moveAwayFrom(cl, startTailLabelXY);
}
if (endHeadText != null && endHeadLabelXY != null && PositionableUtils.intersect(cl, endHeadLabelXY)) { if (endHeadText != null && endHeadLabelXY != null && PositionableUtils.intersect(cl, endHeadLabelXY))
endHeadLabelXY = PositionableUtils.moveAwayFrom(cl, endHeadLabelXY); endHeadLabelXY = PositionableUtils.moveAwayFrom(cl, endHeadLabelXY);
}
} }
// final Positionable start = getStartTailPositionnable(); // final Positionable start = getStartTailPositionnable();
@ -993,12 +972,12 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public Point2D getMyPoint(IEntity entity) { public Point2D getMyPoint(IEntity entity) {
if (link.getEntity1() == entity) { if (link.getEntity1() == entity)
return moveDelta(dotPath.getStartPoint()); return moveDelta(dotPath.getStartPoint());
}
if (link.getEntity2() == entity) { if (link.getEntity2() == entity)
return moveDelta(dotPath.getEndPoint()); return moveDelta(dotPath.getEndPoint());
}
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -1011,25 +990,27 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
} }
public Point2D getStartContactPoint() { public Point2D getStartContactPoint() {
final Point2D start = dotPath.getStartPoint(); if (dotPath == null)
if (start == null) {
return null; return null;
} final Point2D start = dotPath.getStartPoint();
if (start == null)
return null;
return new Point2D.Double(dx + start.getX(), dy + start.getY()); return new Point2D.Double(dx + start.getX(), dy + start.getY());
} }
public Point2D getEndContactPoint() { public Point2D getEndContactPoint() {
final Point2D end = dotPath.getEndPoint(); final Point2D end = dotPath.getEndPoint();
if (end == null) { if (end == null)
return null; return null;
}
return new Point2D.Double(dx + end.getX(), dy + end.getY()); return new Point2D.Double(dx + end.getX(), dy + end.getY());
} }
public IEntity getOther(IEntity entity) { public IEntity getOther(IEntity entity) {
if (link.contains(entity)) { if (link.contains(entity))
return link.getOther(entity); return link.getOther(entity);
}
return null; return null;
} }

View File

@ -270,6 +270,8 @@ public class ImageBuilder {
final Scale scale = titledDiagram == null ? null : titledDiagram.getScale(); final Scale scale = titledDiagram == null ? null : titledDiagram.getScale();
final double scaleFactor = (scale == null ? 1 : scale.getScale(dim.getWidth(), dim.getHeight())) * getDpi() final double scaleFactor = (scale == null ? 1 : scale.getScale(dim.getWidth(), dim.getHeight())) * getDpi()
/ 96.0; / 96.0;
if (scaleFactor <= 0)
throw new IllegalStateException("Bad scaleFactor");
UGraphic ug = createUGraphic(fileFormatOption, dim, animationArg, dx, dy, scaleFactor); UGraphic ug = createUGraphic(fileFormatOption, dim, animationArg, dx, dy, scaleFactor);
maybeDrawBorder(ug, dim); maybeDrawBorder(ug, dim);
if (randomPixel) { if (randomPixel) {
@ -442,8 +444,8 @@ public class ImageBuilder {
} }
private UGraphic createUGraphicPNG(double scaleFactor, final Dimension2D dim, Animation affineTransforms, private UGraphic createUGraphicPNG(double scaleFactor, final Dimension2D dim, Animation affineTransforms, double dx,
double dx, double dy, String watermark) { double dy, String watermark) {
Color backColor = getDefaultBackColor(); Color backColor = getDefaultBackColor();
if (this.backcolor instanceof HColorSimple) { if (this.backcolor instanceof HColorSimple) {

View File

@ -150,6 +150,14 @@ public class HColorSimple extends HColorAbstract implements HColor {
return monochrome; return monochrome;
} }
public boolean isGray() {
if (monochrome)
return true;
if (color.getRed() == color.getGreen() && color.getGreen() == color.getBlue())
return true;
return false;
}
public static HColorSimple unlinear(HColorSimple color1, HColorSimple color2, int completionInt) { public static HColorSimple unlinear(HColorSimple color1, HColorSimple color2, int completionInt) {
final HSLColor col1 = new HSLColor(color1.color); final HSLColor col1 = new HSLColor(color1.color);
final HSLColor col2 = new HSLColor(color2.color); final HSLColor col2 = new HSLColor(color2.color);

View File

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