plantuml/src/net/sourceforge/plantuml/cucadiagram/Display.java

661 lines
23 KiB
Java
Raw Normal View History

2013-12-10 19:36:50 +00:00
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
2022-03-07 19:33:46 +00:00
* (C) Copyright 2009-2023, Arnaud Roques
2013-12-10 19:36:50 +00:00
*
2016-03-06 16:47:34 +00:00
* Project Info: http://plantuml.com
2013-12-10 19:36:50 +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:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
2013-12-10 19:36:50 +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
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.cucadiagram;
import java.util.ArrayList;
import java.util.Arrays;
2015-06-20 10:54:49 +00:00
import java.util.Collection;
2013-12-10 19:36:50 +00:00
import java.util.Collections;
import java.util.List;
2020-12-14 18:31:06 +00:00
import java.util.ListIterator;
2021-05-09 21:14:40 +00:00
import java.util.Objects;
2020-06-21 20:31:45 +00:00
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2013-12-10 19:36:50 +00:00
2017-04-26 17:48:37 +00:00
import net.sourceforge.plantuml.BackSlash;
2019-03-29 22:14:07 +00:00
import net.sourceforge.plantuml.Guillemet;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.ISkinSimple;
2017-02-26 16:26:11 +00:00
import net.sourceforge.plantuml.LineBreakStrategy;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.SpriteContainer;
2013-12-10 19:36:50 +00:00
import net.sourceforge.plantuml.UrlBuilder;
2022-03-13 12:22:51 +00:00
import net.sourceforge.plantuml.UrlMode;
2016-05-31 19:41:55 +00:00
import net.sourceforge.plantuml.command.regex.Matcher2;
2019-11-03 17:40:03 +00:00
import net.sourceforge.plantuml.command.regex.MyPattern;
2016-05-31 19:41:55 +00:00
import net.sourceforge.plantuml.command.regex.Pattern2;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.creole.Sheet;
import net.sourceforge.plantuml.creole.SheetBlock1;
import net.sourceforge.plantuml.creole.SheetBlock2;
2021-02-02 10:12:15 +00:00
import net.sourceforge.plantuml.creole.legacy.CreoleParser;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.graphic.CircledCharacter;
import net.sourceforge.plantuml.graphic.FontConfiguration;
2015-04-07 18:18:37 +00:00
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.graphic.TextBlock;
2016-07-04 19:06:50 +00:00
import net.sourceforge.plantuml.graphic.TextBlockSprited;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.VerticalAlignment;
import net.sourceforge.plantuml.sequencediagram.MessageNumber;
2018-10-21 19:44:14 +00:00
import net.sourceforge.plantuml.skin.VisibilityModifier;
2020-03-03 22:29:34 +00:00
import net.sourceforge.plantuml.style.PName;
2019-08-26 17:07:21 +00:00
import net.sourceforge.plantuml.style.Style;
2022-06-06 12:36:58 +00:00
import net.sourceforge.plantuml.style.Value;
import net.sourceforge.plantuml.style.ValueNull;
2015-07-11 09:32:49 +00:00
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UStroke;
2020-03-18 10:50:02 +00:00
import net.sourceforge.plantuml.ugraphic.color.HColor;
2021-02-02 10:12:15 +00:00
import net.sourceforge.plantuml.ugraphic.color.NoSuchColorException;
2022-12-17 11:01:10 +00:00
import net.sourceforge.plantuml.utils.StringLocated;
2013-12-10 19:36:50 +00:00
public class Display implements Iterable<CharSequence> {
2019-03-29 22:14:07 +00:00
private final List<CharSequence> displayData;
2015-04-07 18:18:37 +00:00
private final HorizontalAlignment naturalHorizontalAlignment;
2015-07-11 09:32:49 +00:00
private final boolean isNull;
private final CreoleMode defaultCreoleMode;
2022-06-06 12:36:58 +00:00
private final boolean showStereotype;
2015-07-11 09:32:49 +00:00
2022-06-06 12:36:58 +00:00
public final static Display NULL = new Display(true, null, null, true, CreoleMode.FULL);
2022-11-04 17:36:03 +00:00
// @Override
// public int hashCode() {
// if (isNull)
// return 42;
// return displayData.hashCode();
// }
//
// @Override
// public boolean equals(Object other) {
// return this.displayData.equals(((Display) other).displayData);
// }
public boolean equalsLike(Display other) {
return this.displayData.equals(other.displayData);
}
2022-06-06 12:36:58 +00:00
public boolean showStereotype() {
return showStereotype;
}
2015-04-07 18:18:37 +00:00
2020-03-03 22:29:34 +00:00
public Display withoutStereotypeIfNeeded(Style usedStyle) {
2021-12-06 18:58:08 +00:00
if (this == NULL)
return NULL;
2022-06-06 12:36:58 +00:00
final Value showStereotype = usedStyle.value(PName.ShowStereotype);
if (showStereotype instanceof ValueNull || showStereotype.asBoolean())
2020-03-03 22:29:34 +00:00
return this;
2021-12-06 18:58:08 +00:00
2022-06-06 12:36:58 +00:00
return new Display(false, this, this.defaultCreoleMode);
2021-12-06 18:58:08 +00:00
2019-03-29 22:14:07 +00:00
}
2020-03-18 10:50:02 +00:00
public Stereotype getStereotypeIfAny() {
2021-12-06 18:58:08 +00:00
for (CharSequence cs : displayData)
if (cs instanceof Stereotype)
2020-03-18 10:50:02 +00:00
return (Stereotype) cs;
2021-12-06 18:58:08 +00:00
2020-03-18 10:50:02 +00:00
return null;
}
2018-08-26 12:09:50 +00:00
public Display replaceBackslashT() {
2022-06-06 12:36:58 +00:00
final Display result = new Display(this.showStereotype, this, defaultCreoleMode);
2019-03-29 22:14:07 +00:00
for (int i = 0; i < result.displayData.size(); i++) {
final CharSequence s = displayData.get(i);
2021-12-06 18:58:08 +00:00
if (s.toString().contains("\\t"))
2019-03-29 22:14:07 +00:00
result.displayData.set(i, s.toString().replace("\\t", "\t"));
2018-08-26 12:09:50 +00:00
}
return result;
}
2018-03-09 21:37:34 +00:00
public Display replace(String src, String dest) {
2021-05-14 08:42:57 +00:00
final List<CharSequence> newDisplay = new ArrayList<>();
2019-03-29 22:14:07 +00:00
for (CharSequence cs : displayData) {
2021-12-06 18:58:08 +00:00
if (cs.toString().contains(src))
2018-03-09 21:37:34 +00:00
cs = cs.toString().replace(src, dest);
2021-12-06 18:58:08 +00:00
2018-03-09 21:37:34 +00:00
newDisplay.add(cs);
}
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, newDisplay, naturalHorizontalAlignment, isNull, defaultCreoleMode);
2018-03-09 21:37:34 +00:00
}
2015-04-07 18:18:37 +00:00
public boolean isWhite() {
2019-03-29 22:14:07 +00:00
return displayData == null || displayData.size() == 0
|| (displayData.size() == 1 && displayData.get(0).toString().matches("\\s*"));
2015-04-07 18:18:37 +00:00
}
public static Display empty() {
2022-06-06 12:36:58 +00:00
return new Display(true, (HorizontalAlignment) null, false, CreoleMode.FULL);
2015-04-07 18:18:37 +00:00
}
public static Display create(CharSequence... s) {
return create(Arrays.asList(s));
}
2021-02-02 10:12:15 +00:00
public static Display createFoo(List<StringLocated> data) throws NoSuchColorException {
2021-05-14 08:42:57 +00:00
final List<CharSequence> tmp = new ArrayList<>();
2021-12-06 18:58:08 +00:00
for (StringLocated s : data)
2019-03-29 22:14:07 +00:00
tmp.add(s.getString());
2021-12-06 18:58:08 +00:00
2021-02-02 10:12:15 +00:00
final Display result = create(tmp);
CreoleParser.checkColor(result);
return result;
2019-03-29 22:14:07 +00:00
}
2022-11-04 17:36:03 +00:00
// private static List<String> skip(String type, Iterator<StringLocated> it) {
// final List<String> result = new ArrayList<String>();
// result.add("@start" + type);
// int nested = 1;
// while (it.hasNext()) {
// final StringLocated s2 = it.next();
// result.add(s2.getString());
// if (s2.getTrimmed().getString().startsWith(EmbeddedDiagram.EMBEDDED_START))
// nested++;
// else if (s2.getTrimmed().getString().equals(EmbeddedDiagram.EMBEDDED_END)) {
// nested--;
// if (nested == 0)
// break;
// }
// }
// result.add("@end" + type);
// return result;
// }
2015-06-20 10:54:49 +00:00
public static Display create(Collection<? extends CharSequence> other) {
2022-06-06 12:36:58 +00:00
return new Display(true, other, null, false, CreoleMode.FULL);
2015-04-07 18:18:37 +00:00
}
public static Display getWithNewlines(Code s) {
2019-12-10 21:45:49 +00:00
return getWithNewlines(s.getName());
2015-04-07 18:18:37 +00:00
}
2021-02-02 10:12:15 +00:00
public static Display getWithNewlines2(String s) throws NoSuchColorException {
final Display result = getWithNewlines(s);
CreoleParser.checkColor(result);
return result;
}
2015-04-07 18:18:37 +00:00
public static Display getWithNewlines(String s) {
2021-12-06 18:58:08 +00:00
if (s == null)
2015-07-11 09:32:49 +00:00
return NULL;
2021-12-06 18:58:08 +00:00
2021-05-14 08:42:57 +00:00
final List<String> result = new ArrayList<>();
2015-04-07 18:18:37 +00:00
final StringBuilder current = new StringBuilder();
HorizontalAlignment naturalHorizontalAlignment = null;
2017-06-05 11:27:21 +00:00
boolean rawMode = false;
2015-04-07 18:18:37 +00:00
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
2017-04-05 17:37:42 +00:00
final String sub = s.substring(i);
2021-12-06 18:58:08 +00:00
if (sub.startsWith("<math>") || sub.startsWith("<latex>") || sub.startsWith("[["))
2017-06-05 11:27:21 +00:00
rawMode = true;
2021-12-06 18:58:08 +00:00
else if (sub.startsWith("</math>") || sub.startsWith("</latex>") || sub.startsWith("]]"))
2017-06-05 11:27:21 +00:00
rawMode = false;
2021-12-06 18:58:08 +00:00
2017-06-05 11:27:21 +00:00
if (rawMode == false && c == '\\' && i < s.length() - 1) {
2015-04-07 18:18:37 +00:00
final char c2 = s.charAt(i + 1);
i++;
if (c2 == 'n' || c2 == 'r' || c2 == 'l') {
2021-12-06 18:58:08 +00:00
if (c2 == 'r')
2015-04-07 18:18:37 +00:00
naturalHorizontalAlignment = HorizontalAlignment.RIGHT;
2021-12-06 18:58:08 +00:00
else if (c2 == 'l')
2015-04-07 18:18:37 +00:00
naturalHorizontalAlignment = HorizontalAlignment.LEFT;
2021-12-06 18:58:08 +00:00
2015-04-07 18:18:37 +00:00
result.add(current.toString());
current.setLength(0);
} else if (c2 == 't') {
current.append('\t');
} else if (c2 == '\\') {
current.append(c2);
} else {
current.append(c);
current.append(c2);
}
2017-04-26 17:48:37 +00:00
} else if (c == BackSlash.hiddenNewLine()) {
2015-05-31 18:56:03 +00:00
result.add(current.toString());
current.setLength(0);
2015-04-07 18:18:37 +00:00
} else {
current.append(c);
}
}
result.add(current.toString());
2022-06-06 12:36:58 +00:00
return new Display(true, result, naturalHorizontalAlignment, false, CreoleMode.FULL);
2015-04-07 18:18:37 +00:00
}
2013-12-10 19:36:50 +00:00
2022-06-06 12:36:58 +00:00
private Display(boolean showStereotype, Display other, CreoleMode mode) {
this(showStereotype, other.naturalHorizontalAlignment, other.isNull, mode);
2019-03-29 22:14:07 +00:00
this.displayData.addAll(other.displayData);
2013-12-10 19:36:50 +00:00
}
2022-06-06 12:36:58 +00:00
private Display(boolean showStereotype, HorizontalAlignment naturalHorizontalAlignment, boolean isNull,
CreoleMode defaultCreoleMode) {
this.showStereotype = showStereotype;
2015-07-11 09:32:49 +00:00
this.defaultCreoleMode = defaultCreoleMode;
this.isNull = isNull;
2019-03-29 22:14:07 +00:00
this.displayData = isNull ? null : new ArrayList<CharSequence>();
2015-07-11 09:32:49 +00:00
this.naturalHorizontalAlignment = isNull ? null : naturalHorizontalAlignment;
2015-04-07 18:18:37 +00:00
}
2022-06-06 12:36:58 +00:00
private Display(boolean showStereotype, Collection<? extends CharSequence> other,
HorizontalAlignment naturalHorizontalAlignment, boolean isNull, CreoleMode defaultCreoleMode) {
this(showStereotype, naturalHorizontalAlignment, isNull, defaultCreoleMode);
2021-12-06 18:58:08 +00:00
if (isNull == false)
2022-11-04 17:36:03 +00:00
// this.displayData.addAll(manageEmbeddedDiagrams(other));
this.displayData.addAll(other);
}
// private static List<CharSequence> manageEmbeddedDiagrams(final Collection<? extends CharSequence> strings) {
// System.err.println("tata=" + strings);
// final List<CharSequence> result = new ArrayList<>();
// final Iterator<? extends CharSequence> it = strings.iterator();
// while (it.hasNext()) {
// CharSequence s = it.next();
// if (s instanceof String == false)
// System.err.println("s=" + s.getClass());
// final String type = EmbeddedDiagram.getEmbeddedType(s);
// if (type != null) {
// final List<CharSequence> other = new ArrayList<>();
// other.add("@start" + type);
// int nested = 1;
// while (it.hasNext()) {
// final CharSequence s2 = it.next();
// if (StringUtils.trin(s2.toString()).equals(EmbeddedDiagram.EMBEDDED_END)) {
// nested--;
// if (nested == 0)
// break;
// }
// if (StringUtils.trin(s2.toString()).startsWith(EmbeddedDiagram.EMBEDDED_START))
// nested++;
//
// other.add(s2);
// }
// other.add("@end" + type);
// s = new EmbeddedDiagram(Display.create(other));
// }
// result.add(s);
// }
// return result;
// }
2013-12-10 19:36:50 +00:00
2022-08-24 16:46:33 +00:00
public Display manageGuillemet(boolean manageVisibilityModifier) {
2021-05-14 08:42:57 +00:00
final List<CharSequence> result = new ArrayList<>();
2018-10-21 19:44:14 +00:00
boolean first = true;
2019-03-29 22:14:07 +00:00
for (CharSequence line : displayData) {
2022-11-04 17:36:03 +00:00
String lineString = line.toString();
if (manageVisibilityModifier && first && VisibilityModifier.isVisibilityCharacter(line))
lineString = lineString.substring(1).trim();
final String withGuillement = Guillemet.GUILLEMET.manageGuillemet(lineString);
result.add(withGuillement);
2021-12-06 18:58:08 +00:00
2018-10-21 19:44:14 +00:00
first = false;
2016-11-04 21:39:29 +00:00
}
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, result, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2016-11-04 21:39:29 +00:00
}
2017-11-20 16:10:36 +00:00
public Display withPage(int page, int lastpage) {
2021-12-06 18:58:08 +00:00
if (displayData == null)
2017-11-20 16:10:36 +00:00
return this;
2021-12-06 18:58:08 +00:00
2021-05-14 08:42:57 +00:00
final List<CharSequence> result = new ArrayList<>();
2019-03-29 22:14:07 +00:00
for (CharSequence line : displayData) {
2017-11-20 16:10:36 +00:00
line = line.toString().replace("%page%", "" + page);
line = line.toString().replace("%lastpage%", "" + lastpage);
result.add(line);
}
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, result, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2017-11-20 16:10:36 +00:00
}
2019-11-03 17:40:03 +00:00
public Display removeEndingStereotype() {
final Matcher2 m = patternStereotype.matcher(displayData.get(displayData.size() - 1));
if (m.matches()) {
2021-05-14 08:42:57 +00:00
final List<CharSequence> result = new ArrayList<>(this.displayData);
2019-11-03 17:40:03 +00:00
result.set(result.size() - 1, m.group(1));
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, result, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2019-11-03 17:40:03 +00:00
}
return this;
}
public final static Pattern2 patternStereotype = MyPattern.cmpile("^(.*?)(?:\\<\\<\\s*(.*)\\s*\\>\\>)\\s*$");
public String getEndingStereotype() {
final Matcher2 m = patternStereotype.matcher(displayData.get(displayData.size() - 1));
2021-12-06 18:58:08 +00:00
if (m.matches())
2019-11-03 17:40:03 +00:00
return m.group(2);
2021-12-06 18:58:08 +00:00
2019-11-03 17:40:03 +00:00
return null;
}
2013-12-10 19:36:50 +00:00
public Display underlined() {
2021-05-14 08:42:57 +00:00
final List<CharSequence> result = new ArrayList<>();
2021-12-06 18:58:08 +00:00
for (CharSequence line : displayData)
2013-12-10 19:36:50 +00:00
result.add("<u>" + line);
2021-12-06 18:58:08 +00:00
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, result, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2015-07-11 09:32:49 +00:00
}
2020-06-21 20:31:45 +00:00
public Display underlinedName() {
final Pattern p = Pattern.compile("^([^:]+?)(\\s*:.+)$");
2021-05-14 08:42:57 +00:00
final List<CharSequence> result = new ArrayList<>();
2020-06-21 20:31:45 +00:00
for (CharSequence line : displayData) {
if (result.size() == 0) {
final Matcher m = p.matcher(line);
if (m.matches())
result.add("<u>" + m.group(1) + "</u>" + m.group(2));
else
result.add("<u>" + line);
} else {
result.add("<u>" + line);
}
}
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, result, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2020-06-21 20:31:45 +00:00
}
2015-07-11 09:32:49 +00:00
public Display withCreoleMode(CreoleMode mode) {
2021-12-06 18:58:08 +00:00
if (isNull)
2015-07-11 09:32:49 +00:00
throw new IllegalArgumentException();
2021-12-06 18:58:08 +00:00
2022-06-06 12:36:58 +00:00
return new Display(this.showStereotype, this, mode);
2013-12-10 19:36:50 +00:00
}
@Override
public String toString() {
2021-12-06 18:58:08 +00:00
if (isNull)
2015-07-11 09:32:49 +00:00
return "NULL";
2021-12-06 18:58:08 +00:00
2019-03-29 22:14:07 +00:00
return displayData.toString();
2013-12-10 19:36:50 +00:00
}
public Display addAll(Display other) {
2022-06-06 12:36:58 +00:00
final Display result = new Display(this.showStereotype, this, this.defaultCreoleMode);
2019-03-29 22:14:07 +00:00
result.displayData.addAll(other.displayData);
2013-12-10 19:36:50 +00:00
return result;
}
public Display addFirst(CharSequence s) {
2022-06-06 12:36:58 +00:00
final Display result = new Display(this.showStereotype, this, this.defaultCreoleMode);
2019-03-29 22:14:07 +00:00
result.displayData.add(0, s);
2013-12-10 19:36:50 +00:00
return result;
}
public Display add(CharSequence s) {
2022-06-06 12:36:58 +00:00
final Display result = new Display(this.showStereotype, this, this.defaultCreoleMode);
2019-03-29 22:14:07 +00:00
result.displayData.add(s);
2013-12-10 19:36:50 +00:00
return result;
}
2017-09-03 16:59:24 +00:00
public Display addGeneric(CharSequence s) {
2022-06-06 12:36:58 +00:00
final Display result = new Display(this.showStereotype, this, this.defaultCreoleMode);
2019-03-29 22:14:07 +00:00
final int size = displayData.size();
2021-12-06 18:58:08 +00:00
if (size == 0)
2019-03-29 22:14:07 +00:00
result.displayData.add("<" + s + ">");
2021-12-06 18:58:08 +00:00
else
2019-03-29 22:14:07 +00:00
result.displayData.set(size - 1, displayData.get(size - 1) + "<" + s + ">");
2021-12-06 18:58:08 +00:00
2017-09-03 16:59:24 +00:00
return result;
}
2013-12-10 19:36:50 +00:00
public int size() {
2021-12-06 18:58:08 +00:00
if (isNull)
2015-07-11 09:32:49 +00:00
return 0;
2021-12-06 18:58:08 +00:00
2019-03-29 22:14:07 +00:00
return displayData.size();
2013-12-10 19:36:50 +00:00
}
public CharSequence get(int i) {
2019-03-29 22:14:07 +00:00
return displayData.get(i);
2013-12-10 19:36:50 +00:00
}
2020-12-14 18:31:06 +00:00
public ListIterator<CharSequence> iterator() {
return Collections.unmodifiableList(displayData).listIterator();
2013-12-10 19:36:50 +00:00
}
public Display subList(int i, int size) {
2022-06-06 12:36:58 +00:00
return new Display(showStereotype, displayData.subList(i, size), this.naturalHorizontalAlignment, this.isNull,
2015-07-11 09:32:49 +00:00
this.defaultCreoleMode);
2013-12-10 19:36:50 +00:00
}
public List<? extends CharSequence> asList() {
2019-03-29 22:14:07 +00:00
return Collections.unmodifiableList(displayData);
2013-12-10 19:36:50 +00:00
}
2022-11-04 17:36:03 +00:00
// public List<StringLocated> as2() {
// final List<StringLocated> result = new ArrayList<>();
// LineLocationImpl location = new LineLocationImpl("inner", null);
// for (CharSequence cs : displayData) {
// location = location.oneLineRead();
// result.add(new StringLocated(cs.toString(), location));
// }
// return Collections.unmodifiableList(result);
// }
2015-06-20 10:54:49 +00:00
2013-12-10 19:36:50 +00:00
public boolean hasUrl() {
2022-03-13 12:22:51 +00:00
final UrlBuilder urlBuilder = new UrlBuilder(null, UrlMode.ANYWHERE);
2021-12-06 18:58:08 +00:00
for (CharSequence s : this)
if (urlBuilder.getUrl(s.toString()) != null)
2013-12-10 19:36:50 +00:00
return true;
2021-12-06 18:58:08 +00:00
2013-12-10 19:36:50 +00:00
return false;
}
2015-04-07 18:18:37 +00:00
public HorizontalAlignment getNaturalHorizontalAlignment() {
return naturalHorizontalAlignment;
}
2016-05-31 19:41:55 +00:00
public List<Display> splitMultiline(Pattern2 separator) {
2021-05-14 08:42:57 +00:00
final List<Display> result = new ArrayList<>();
2022-06-06 12:36:58 +00:00
Display pending = new Display(showStereotype, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2015-05-31 18:56:03 +00:00
result.add(pending);
2019-03-29 22:14:07 +00:00
for (CharSequence line : displayData) {
2016-05-31 19:41:55 +00:00
final Matcher2 m = separator.matcher(line);
2015-05-31 18:56:03 +00:00
if (m.find()) {
final CharSequence s1 = line.subSequence(0, m.start());
2019-03-29 22:14:07 +00:00
pending.displayData.add(s1);
2015-05-31 18:56:03 +00:00
final CharSequence s2 = line.subSequence(m.end(), line.length());
2022-06-06 12:36:58 +00:00
pending = new Display(showStereotype, this.naturalHorizontalAlignment, this.isNull,
this.defaultCreoleMode);
2015-05-31 18:56:03 +00:00
result.add(pending);
2019-03-29 22:14:07 +00:00
pending.displayData.add(s2);
2015-05-31 18:56:03 +00:00
} else {
2019-03-29 22:14:07 +00:00
pending.displayData.add(line);
2015-05-31 18:56:03 +00:00
}
}
return Collections.unmodifiableList(result);
}
2015-07-11 09:32:49 +00:00
// ------
public static boolean isNull(Display display) {
2021-05-09 21:14:40 +00:00
// Objects.requireNonNull(display);
2015-07-11 09:32:49 +00:00
return display == null || display.isNull;
}
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer) {
2020-04-05 15:13:04 +00:00
return create7(fontConfiguration, horizontalAlignment, spriteContainer, CreoleMode.FULL);
2015-07-11 09:32:49 +00:00
}
2020-04-05 15:13:04 +00:00
public TextBlock create7(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2019-05-24 19:59:31 +00:00
ISkinSimple spriteContainer, CreoleMode creoleMode) {
2020-04-05 15:13:04 +00:00
return create0(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode,
null, null);
2015-07-11 09:32:49 +00:00
}
2020-04-05 15:13:04 +00:00
public TextBlock create8(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2018-03-09 21:37:34 +00:00
ISkinSimple spriteContainer, CreoleMode modeSimpleLine, LineBreakStrategy maxMessageSize) {
2020-04-05 15:13:04 +00:00
return create0(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine, null,
2018-07-27 21:56:46 +00:00
null);
2018-03-09 21:37:34 +00:00
}
2020-04-05 15:13:04 +00:00
public TextBlock create9(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2017-02-26 16:26:11 +00:00
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize) {
2020-04-05 15:13:04 +00:00
return create0(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, defaultCreoleMode, null,
2017-02-26 16:26:11 +00:00
null);
}
2020-04-05 15:13:04 +00:00
public TextBlock create0(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2019-05-24 19:59:31 +00:00
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode,
2020-03-18 10:50:02 +00:00
UFont fontForStereotype, HColor htmlColorForStereotype) {
return create0(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, creoleMode,
fontForStereotype, htmlColorForStereotype, 0, 0);
}
public TextBlock create0(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode,
UFont fontForStereotype, HColor htmlColorForStereotype, double marginX1, double marginX2) {
2021-05-09 21:14:40 +00:00
Objects.requireNonNull(maxMessageSize);
2021-12-06 18:58:08 +00:00
if (getNaturalHorizontalAlignment() != null)
2015-07-11 09:32:49 +00:00
horizontalAlignment = getNaturalHorizontalAlignment();
2021-12-06 18:58:08 +00:00
2020-01-12 22:13:17 +00:00
final FontConfiguration stereotypeConfiguration = fontConfiguration.forceFont(fontForStereotype,
htmlColorForStereotype);
2015-07-11 09:32:49 +00:00
if (size() > 0) {
2021-12-06 18:58:08 +00:00
if (get(0) instanceof Stereotype)
2015-07-11 09:32:49 +00:00
return createStereotype(fontConfiguration, horizontalAlignment, spriteContainer, 0, fontForStereotype,
htmlColorForStereotype, maxMessageSize, creoleMode, marginX1, marginX2);
2021-12-06 18:58:08 +00:00
if (get(size() - 1) instanceof Stereotype)
2015-07-11 09:32:49 +00:00
return createStereotype(fontConfiguration, horizontalAlignment, spriteContainer, size() - 1,
fontForStereotype, htmlColorForStereotype, maxMessageSize, creoleMode, marginX1, marginX2);
2021-12-06 18:58:08 +00:00
if (get(0) instanceof MessageNumber)
2020-01-12 22:13:17 +00:00
return createMessageNumber(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize,
stereotypeConfiguration, marginX1, marginX2);
2015-07-11 09:32:49 +00:00
}
2020-01-12 22:13:17 +00:00
return getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, creoleMode,
stereotypeConfiguration, marginX1, marginX2);
2020-01-12 22:13:17 +00:00
}
private TextBlock createStereotype(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2020-03-18 10:50:02 +00:00
SpriteContainer spriteContainer, int position, UFont fontForStereotype, HColor htmlColorForStereotype,
LineBreakStrategy maxMessageSize, CreoleMode creoleMode, double marginX1, double marginX2) {
2020-01-12 22:13:17 +00:00
final Stereotype stereotype = (Stereotype) get(position);
TextBlock circledCharacter = null;
2021-12-06 18:58:08 +00:00
if (stereotype.isSpotted())
2020-01-12 22:13:17 +00:00
circledCharacter = new CircledCharacter(stereotype.getCharacter(), stereotype.getRadius(),
stereotype.getCircledFont(), stereotype.getHtmlColor(), null, fontConfiguration.getColor());
2021-12-06 18:58:08 +00:00
else
2020-01-12 22:13:17 +00:00
circledCharacter = stereotype.getSprite(spriteContainer);
2021-12-06 18:58:08 +00:00
2020-01-12 22:13:17 +00:00
final FontConfiguration stereotypeConfiguration = fontConfiguration.forceFont(fontForStereotype,
htmlColorForStereotype);
final TextBlock result = getCreole(fontConfiguration, horizontalAlignment, (ISkinSimple) spriteContainer,
maxMessageSize, creoleMode, stereotypeConfiguration, marginX1, marginX2);
2021-12-06 18:58:08 +00:00
if (circledCharacter != null)
2020-01-12 22:13:17 +00:00
return new TextBlockSprited(circledCharacter, result);
2021-12-06 18:58:08 +00:00
2020-01-12 22:13:17 +00:00
return result;
2015-07-11 09:32:49 +00:00
}
private TextBlock getCreole(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
2020-01-12 22:13:17 +00:00
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode,
FontConfiguration stereotypeConfiguration, double marginX1, double marginX2) {
2022-11-04 17:36:03 +00:00
final Sheet sheet = spriteContainer
.sheet(fontConfiguration, horizontalAlignment, creoleMode, stereotypeConfiguration).createSheet(this);
2020-04-05 15:13:04 +00:00
final double padding = spriteContainer == null ? 0 : spriteContainer.getPadding();
final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, padding, marginX1, marginX2);
2015-07-11 09:32:49 +00:00
return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5));
}
private TextBlock createMessageNumber(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, FontConfiguration stereotypeConfiguration,
double marginX1, double marginX2) {
2020-03-03 22:29:34 +00:00
TextBlock tb1 = subList(0, 1).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize,
CreoleMode.FULL, stereotypeConfiguration, marginX1, marginX2);
2015-07-11 09:32:49 +00:00
tb1 = TextBlockUtils.withMargin(tb1, 0, 4, 0, 0);
final TextBlock tb2 = subList(1, size()).getCreole(fontConfiguration, horizontalAlignment, spriteContainer,
maxMessageSize, CreoleMode.FULL, stereotypeConfiguration, marginX1, marginX2);
2015-07-11 09:32:49 +00:00
return TextBlockUtils.mergeLR(tb1, tb2, VerticalAlignment.CENTER);
}
2020-05-17 21:15:50 +00:00
public boolean hasSeveralGuideLines() {
return hasSeveralGuideLines(displayData);
}
public static boolean hasSeveralGuideLines(String s) {
final List<String> splitted = Arrays.asList(s.split("\\\\n"));
return hasSeveralGuideLines(splitted);
}
private static boolean hasSeveralGuideLines(Collection<? extends CharSequence> all) {
2021-12-06 18:58:08 +00:00
if (all.size() <= 1)
2020-05-17 21:15:50 +00:00
return false;
2021-12-06 18:58:08 +00:00
2020-05-17 21:15:50 +00:00
for (CharSequence cs : all) {
final String s = cs.toString();
2021-12-06 18:58:08 +00:00
if (s.startsWith("< "))
2020-05-17 21:15:50 +00:00
return true;
2021-12-06 18:58:08 +00:00
if (s.startsWith("> "))
2020-05-17 21:15:50 +00:00
return true;
2021-12-06 18:58:08 +00:00
if (s.endsWith(" <"))
2020-05-17 21:15:50 +00:00
return true;
2021-12-06 18:58:08 +00:00
if (s.endsWith(" >"))
2020-05-17 21:15:50 +00:00
return true;
}
return false;
}
2022-11-04 17:36:03 +00:00
// private Object data;
// private boolean mayHaveEmbedded;
//
// public final Object getCachedDataForPerf() {
// return data;
// }
//
// public final void setCachedDataForPerf(Object data) {
// this.data = data;
// }
//
// public final void setMayHaveEmbedded() {
// this.mayHaveEmbedded = true;
// }
//
// public final boolean mayHaveEmbedded() {
// return mayHaveEmbedded;
// }
2013-12-10 19:36:50 +00:00
}