1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-22 04:55:10 +00:00
Arnaud Roques 2023-06-27 22:04:12 +02:00
parent 968a958b9d
commit 1ef8dd39f9
9 changed files with 207 additions and 133 deletions

View File

@ -1,4 +1,4 @@
# Warning, "version" should be the same in gradle.properties and Version.java # Warning, "version" should be the same in gradle.properties and Version.java
# Any idea anyone how to magically synchronize those :-) ? # Any idea anyone how to magically synchronize those :-) ?
version = 1.2023.10beta1 version = 1.2023.10beta2
org.gradle.workers.max = 3 org.gradle.workers.max = 3

View File

@ -0,0 +1,162 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.filesdiagram;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.plantuml.klimt.LineBreakStrategy;
import net.sourceforge.plantuml.klimt.UStroke;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.creole.CreoleMode;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.creole.Sheet;
import net.sourceforge.plantuml.klimt.creole.SheetBlock1;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.image.Opale;
public class FEntry implements Iterable<FEntry> {
private final ISkinParam skinParam;
private final List<String> note;
private final String name;
private FilesType type;
private List<FEntry> children = new ArrayList<>();
public static FEntry createRoot(ISkinParam skinParam) {
return new FEntry(null, "", FilesType.FOLDER, skinParam);
}
private FEntry(List<String> note, String name, FilesType type, ISkinParam skinParam) {
this.note = note;
this.name = name;
this.type = type;
this.skinParam = skinParam;
}
public void addRawEntry(String raw, ISkinParam skinParam) {
final int x = raw.indexOf('/');
if (x == -1) {
final FEntry result = new FEntry(null, raw, FilesType.DATA, skinParam);
children.add(result);
return;
}
final FEntry folder = getOrCreateFolder(raw.substring(0, x), skinParam);
final String remain = raw.substring(x + 1);
if (remain.length() != 0)
folder.addRawEntry(remain, skinParam);
}
public void addNote(List<String> note, ISkinParam skinParam) {
final FEntry result = new FEntry(note, "NONE", FilesType.NOTE, skinParam);
children.add(result);
}
private FEntry getOrCreateFolder(String folderName, ISkinParam skinParam) {
for (FEntry child : children)
if (child.type == FilesType.FOLDER && child.getName().equals(folderName))
return child;
final FEntry result = new FEntry(null, folderName, FilesType.FOLDER, skinParam);
children.add(result);
return result;
}
@Override
public Iterator<FEntry> iterator() {
return Collections.unmodifiableCollection(children).iterator();
}
public String getName() {
return name;
}
public String getEmoticon() {
if (type == FilesType.FOLDER)
return "<:1f4c2:>";
// return "<:1f4c1:>";
return "<:1f4c4:>";
}
public UGraphic drawAndMove(UGraphic ug, FontConfiguration fontConfiguration, ISkinParam skinParam, double deltax) {
final TextBlock result = getTextBlock(fontConfiguration, skinParam);
result.drawU(ug.apply(UTranslate.dx(deltax)));
ug = ug.apply(UTranslate.dy(result.calculateDimension(ug.getStringBounder()).getHeight() + 2));
for (FEntry child : children)
ug = child.drawAndMove(ug, fontConfiguration, skinParam, deltax + 21);
return ug;
}
private TextBlock getTextBlock(FontConfiguration fontConfiguration, ISkinParam skinParam) {
if (type == FilesType.NOTE)
return createOpale();
final Display display = Display.getWithNewlines(getEmoticon() + getName());
TextBlock result = display.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
return result;
}
private Opale createOpale() {
final StyleSignatureBasic signature = StyleSignatureBasic.of(SName.root, SName.element, SName.timingDiagram,
SName.note);
final Style style = signature.getMergedStyle(skinParam.getCurrentStyleBuilder());
final FontConfiguration fc = FontConfiguration.create(skinParam, style);
final double shadowing = style.value(PName.Shadowing).asDouble();
final HColor borderColor = style.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
final HColor noteBackgroundColor = style.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet());
final UStroke stroke = style.getStroke();
final Sheet sheet = skinParam
.sheet(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), CreoleMode.FULL)
.createSheet(Display.create(note));
final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding());
final Opale opale = new Opale(shadowing, borderColor, noteBackgroundColor, sheet1, false, stroke);
return opale;
}
}

View File

@ -36,7 +36,10 @@ package net.sourceforge.plantuml.filesdiagram;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.UmlDiagram;
@ -57,15 +60,27 @@ public class FilesDiagram extends UmlDiagram {
final Iterator<StringLocated> it = source.iterator2(); final Iterator<StringLocated> it = source.iterator2();
it.next(); it.next();
while (true) { while (it.hasNext()) {
final String line = it.next().getString(); final String line = it.next().getString();
if (it.hasNext() == false) if (line.startsWith("/"))
break; this.list.addRawEntry(line.substring(1));
this.list.add(line); else if (line.startsWith("<note>"))
this.list.addNote(getNote(it));
} }
} }
private List<String> getNote(Iterator<StringLocated> it) {
final List<String> result = new ArrayList<String>();
while (it.hasNext()) {
final String line = it.next().getString();
if (line.startsWith("</note>"))
return result;
result.add(line);
}
return Collections.unmodifiableList(result);
}
public DiagramDescription getDescription() { public DiagramDescription getDescription() {
return new DiagramDescription("(Files)"); return new DiagramDescription("(Files)");
} }

View File

@ -1,111 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*/
package net.sourceforge.plantuml.filesdiagram;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.style.ISkinParam;
public class FilesEntry implements Iterable<FilesEntry> {
private final String name;
private FilesType type;
private List<FilesEntry> children = new ArrayList<>();
public FilesEntry(String name, FilesType type) {
this.name = name;
this.type = type;
}
public FilesEntry addRawEntry(String raw) {
final int x = raw.indexOf('/');
if (x == -1) {
final FilesEntry result = new FilesEntry(raw, FilesType.DATA);
children.add(result);
return result;
}
final FilesEntry folder = getOrCreateFolder(raw.substring(0, x));
final String remain = raw.substring(x + 1);
if (remain.length() == 0)
return folder;
return folder.addRawEntry(remain);
}
private FilesEntry getOrCreateFolder(String folderName) {
for (FilesEntry child : children)
if (child.type == FilesType.FOLDER && child.getName().equals(folderName))
return child;
final FilesEntry result = new FilesEntry(folderName, FilesType.FOLDER);
children.add(result);
return result;
}
@Override
public Iterator<FilesEntry> iterator() {
return Collections.unmodifiableCollection(children).iterator();
}
public String getName() {
return name;
}
public String getEmoticon() {
if (type == FilesType.FOLDER)
return "<:1f4c2:>";
// return "<:1f4c1:>";
return "<:1f4c4:>";
}
public UGraphic drawAndMove(UGraphic ug, FontConfiguration fontConfiguration, ISkinParam skinParam, double deltax) {
final Display display = Display.getWithNewlines(getEmoticon() + getName());
TextBlock result = display.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
result.drawU(ug.apply(UTranslate.dx(deltax)));
ug = ug.apply(UTranslate.dy(result.calculateDimension(ug.getStringBounder()).getHeight() + 2));
for (FilesEntry child : children)
ug = child.drawAndMove(ug, fontConfiguration, skinParam, deltax + 21);
return ug;
}
}

View File

@ -34,6 +34,8 @@
*/ */
package net.sourceforge.plantuml.filesdiagram; package net.sourceforge.plantuml.filesdiagram;
import java.util.List;
import net.sourceforge.plantuml.klimt.drawing.UGraphic; import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration; import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.font.StringBounder; import net.sourceforge.plantuml.klimt.font.StringBounder;
@ -46,10 +48,11 @@ public class FilesListing extends AbstractTextBlock {
private final ISkinParam skinParam; private final ISkinParam skinParam;
private final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.courier(14)); private final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.courier(14));
private final FilesEntry root = new FilesEntry("", FilesType.FOLDER); private final FEntry root;
public FilesListing(ISkinParam skinParam) { public FilesListing(ISkinParam skinParam) {
this.skinParam = skinParam; this.skinParam = skinParam;
this.root = FEntry.createRoot(skinParam);
} }
@Override @Override
@ -59,13 +62,16 @@ public class FilesListing extends AbstractTextBlock {
@Override @Override
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
for (FilesEntry ent : root) for (FEntry ent : root)
ug = ent.drawAndMove(ug, fontConfiguration, skinParam, 0); ug = ent.drawAndMove(ug, fontConfiguration, skinParam, 0);
} }
public void add(String line) { public void addRawEntry(String raw) {
if (line.startsWith("/")) root.addRawEntry(raw, skinParam);
root.addRawEntry(line.substring(1)); }
public void addNote(List<String> note) {
root.addNote(note, skinParam);
} }
} }

View File

@ -35,6 +35,6 @@
package net.sourceforge.plantuml.filesdiagram; package net.sourceforge.plantuml.filesdiagram;
public enum FilesType { public enum FilesType {
FOLDER, DATA; FOLDER, DATA, NOTE;
} }

View File

@ -70,7 +70,9 @@ public class UFont {
} }
public static UFont build(String fontFamily, int fontStyle, int fontSize) { public static UFont build(String fontFamily, int fontStyle, int fontSize) {
return new UFont(buildFont(fontFamily, fontStyle, fontSize), fontFamily); final String family = getExistingFontFamily(fontFamily);
final Font font = new Font(family, fontStyle, fontSize);
return new UFont(font, fontFamily);
} }
private UFont(Font font, String family) { private UFont(Font font, String family) {
@ -78,16 +80,16 @@ public class UFont {
this.family = family; this.family = family;
} }
private static Font buildFont(String fontFamily, int fontStyle, int fontSize) { public static String getExistingFontFamily(String fontFamily) {
if (fontFamily.contains(",")) if (fontFamily.contains(",")) {
for (String name : fontFamily.split(",")) { for (String name : fontFamily.split(",")) {
name = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(name.trim()).trim(); name = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(name.trim()).trim();
if (doesFamilyExists(name)) if (doesFamilyExists(name))
return new Font(name, fontStyle, fontSize); return name;
} }
return "SansSerif";
return new Font(fontFamily, fontStyle, fontSize); }
return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(fontFamily.trim()).trim();
} }
private static boolean doesFamilyExists(String name) { private static boolean doesFamilyExists(String name) {

View File

@ -58,7 +58,7 @@ import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.TextBlockUtils; import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
public class Style { public class Style {
// ::remove file when __HAXE__ // ::remove file when __HAXE__
private final Map<PName, Value> map; private final Map<PName, Value> map;
private final StyleSignatureBasic signature; private final StyleSignatureBasic signature;
@ -180,8 +180,8 @@ public class Style {
} }
public UFont getUFont() { public UFont getUFont() {
final String family = StringUtils final String fontName = value(PName.FontName).asString();
.eventuallyRemoveStartingAndEndingDoubleQuote(value(PName.FontName).asString()); final String family = UFont.getExistingFontFamily(fontName);
final int fontStyle = value(PName.FontStyle).asFontStyle(); final int fontStyle = value(PName.FontStyle).asFontStyle();
int size = value(PName.FontSize).asInt(true); int size = value(PName.FontSize).asInt(true);
if (size == -1) if (size == -1)

View File

@ -46,7 +46,7 @@ public class Version {
// Warning, "version" should be the same in gradle.properties and Version.java // Warning, "version" should be the same in gradle.properties and Version.java
// Any idea anyone how to magically synchronize those :-) ? // Any idea anyone how to magically synchronize those :-) ?
private static final String version = "1.2023.10beta1"; private static final String version = "1.2023.10beta2";
public static String versionString() { public static String versionString() {
return version; return version;