From bdc0eb9709fe707b835065ea94ef17c2857f8dd8 Mon Sep 17 00:00:00 2001 From: Arnaud Roques Date: Sun, 21 Mar 2021 13:52:20 +0100 Subject: [PATCH] Add a first test using Debug format output --- src/net/sourceforge/plantuml/FileFormat.java | 3 +- .../plantuml/graphic/FontConfiguration.java | 4 + .../plantuml/ugraphic/ImageBuilder.java | 17 +- .../sourceforge/plantuml/ugraphic/UFont.java | 8 + .../plantuml/ugraphic/color/HColorSimple.java | 4 + .../ugraphic/debug/StringBounderDebug.java | 52 +++++ .../ugraphic/debug/UGraphicDebug.java | 187 ++++++++++++++++++ test/demo1/SimpleSequenceDiagramTest.java | 168 ++++++++++++++++ 8 files changed, 435 insertions(+), 8 deletions(-) create mode 100644 src/net/sourceforge/plantuml/ugraphic/debug/StringBounderDebug.java create mode 100644 src/net/sourceforge/plantuml/ugraphic/debug/UGraphicDebug.java create mode 100644 test/demo1/SimpleSequenceDiagramTest.java diff --git a/src/net/sourceforge/plantuml/FileFormat.java b/src/net/sourceforge/plantuml/FileFormat.java index d6ad5f83a..59a146b12 100644 --- a/src/net/sourceforge/plantuml/FileFormat.java +++ b/src/net/sourceforge/plantuml/FileFormat.java @@ -80,7 +80,8 @@ public enum FileFormat { LATEX_NO_PREAMBLE("application/x-latex"), BASE64("text/plain; charset=x-user-defined"), BRAILLE_PNG("image/png"), - PREPROC("text/plain"); + PREPROC("text/plain"), + DEBUG("text/plain"); private final String mimeType; diff --git a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java index 6af8fa063..d9512cab7 100644 --- a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java +++ b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java @@ -65,6 +65,10 @@ public class FontConfiguration { private final boolean useUnderlineForHyperlink; private final int tabSize; + public String toStringDebug() { + return getFont().toStringDebug() + " " + styles.toString(); + } + public FontConfiguration(UFont font, HColor color, HColor hyperlinkColor, boolean useUnderlineForHyperlink) { this(font, color, hyperlinkColor, useUnderlineForHyperlink, 8); } diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 76a65d864..edcca6ba6 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -79,6 +79,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorGradient; import net.sourceforge.plantuml.ugraphic.color.HColorSimple; import net.sourceforge.plantuml.ugraphic.color.HColorUtils; import net.sourceforge.plantuml.ugraphic.crossing.UGraphicCrossing; +import net.sourceforge.plantuml.ugraphic.debug.UGraphicDebug; import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; import net.sourceforge.plantuml.ugraphic.hand.UGraphicHandwritten; @@ -281,17 +282,16 @@ public class ImageBuilder { private UGraphic2 createUGraphic(FileFormatOption option, long seed, final Dimension2D dim, Animation animationArg, double dx, double dy) { final ColorMapper colorMapper = param.getColorMapper(); - final double scaleFactor = (param.getScale() == null ? 1 : param.getScale().getScale(dim.getWidth(), dim.getHeight())) - * param.getDpi() / 96.0; + final double scaleFactor = (param.getScale() == null ? 1 + : param.getScale().getScale(dim.getWidth(), dim.getHeight())) * param.getDpi() / 96.0; final FileFormat fileFormat = option.getFileFormat(); switch (fileFormat) { case PNG: return createUGraphicPNG(colorMapper, scaleFactor, dim, param.getBackcolor(), animationArg, dx, dy, option.getWatermark()); case SVG: - return createUGraphicSVG(colorMapper, scaleFactor, dim, param.getBackcolor(), - option.getSvgLinkTarget(), option.getHoverColor(), seed, option.getPreserveAspectRatio(), - param.getlengthAdjust()); + return createUGraphicSVG(colorMapper, scaleFactor, dim, param.getBackcolor(), option.getSvgLinkTarget(), + option.getHoverColor(), seed, option.getPreserveAspectRatio(), param.getlengthAdjust()); case EPS: return new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); case EPS_TEXT: @@ -309,13 +309,16 @@ public class ImageBuilder { case UTXT: case ATXT: return new UGraphicTxt(); + case DEBUG: + return new UGraphicDebug(); default: throw new UnsupportedOperationException(fileFormat.toString()); } } - private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scaleFactor, Dimension2D dim, final HColor suggested, - String svgLinkTarget, String hover, long seed, String preserveAspectRatio, LengthAdjust lengthAdjust) { + private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scaleFactor, Dimension2D dim, + final HColor suggested, String svgLinkTarget, String hover, long seed, String preserveAspectRatio, + LengthAdjust lengthAdjust) { HColor backColor = HColorUtils.WHITE; if (suggested instanceof HColorSimple) { backColor = suggested; diff --git a/src/net/sourceforge/plantuml/ugraphic/UFont.java b/src/net/sourceforge/plantuml/ugraphic/UFont.java index a745f60a3..6149a71f1 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UFont.java +++ b/src/net/sourceforge/plantuml/ugraphic/UFont.java @@ -62,6 +62,14 @@ public class UFont { } } + public String toStringDebug() { + final StringBuilder sb = new StringBuilder(); + sb.append(font.getFontName()); + sb.append("/"); + sb.append(font.getSize()); + return sb.toString(); + } + public UFont(String fontFamily, int fontStyle, int fontSize) { this(buildFont(fontFamily, fontStyle, fontSize), fontFamily); } diff --git a/src/net/sourceforge/plantuml/ugraphic/color/HColorSimple.java b/src/net/sourceforge/plantuml/ugraphic/color/HColorSimple.java index b3d7de7ff..a3e0726df 100644 --- a/src/net/sourceforge/plantuml/ugraphic/color/HColorSimple.java +++ b/src/net/sourceforge/plantuml/ugraphic/color/HColorSimple.java @@ -92,4 +92,8 @@ public class HColorSimple extends HColorAbstract implements HColor { return diffRed * .3 + diffGreen * .59 + diffBlue * .11; } + public final boolean isMonochrome() { + return monochrome; + } + } diff --git a/src/net/sourceforge/plantuml/ugraphic/debug/StringBounderDebug.java b/src/net/sourceforge/plantuml/ugraphic/debug/StringBounderDebug.java new file mode 100644 index 000000000..53af864be --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/debug/StringBounderDebug.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.ugraphic.debug; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UFont; + +public class StringBounderDebug implements StringBounder { + + public Dimension2D calculateDimension(UFont font, String text) { + final double size = font.getSize2D(); + final double height = size; + final double width = size * text.length(); + return new Dimension2DDouble(width, height); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/debug/UGraphicDebug.java b/src/net/sourceforge/plantuml/ugraphic/debug/UGraphicDebug.java new file mode 100644 index 000000000..74d468409 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/debug/UGraphicDebug.java @@ -0,0 +1,187 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + */ +package net.sourceforge.plantuml.ugraphic.debug; + +import java.awt.Color; +import java.awt.geom.Point2D; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UGraphic2; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; +import net.sourceforge.plantuml.ugraphic.color.ColorMapperIdentity; +import net.sourceforge.plantuml.ugraphic.color.HColor; +import net.sourceforge.plantuml.ugraphic.color.HColorSimple; + +public class UGraphicDebug extends AbstractCommonUGraphic implements ClipContainer, UGraphic2 { + + private final List output; + + @Override + protected AbstractCommonUGraphic copyUGraphic() { + return new UGraphicDebug(this, output); + } + + private UGraphicDebug(UGraphicDebug other, List output) { + super(other); + this.output = output; + } + + public UGraphicDebug() { + super(new ColorMapperIdentity()); + this.output = new ArrayList(); + } + + public StringBounder getStringBounder() { + return new StringBounderDebug(); + } + + public void draw(UShape shape) { + final int dx = (int) getTranslateX(); + final int dy = (int) getTranslateY(); + if (shape instanceof ULine) { + outLine((ULine) shape); + } else if (shape instanceof URectangle) { + outRectangle((URectangle) shape); + } else if (shape instanceof UText) { + outText((UText) shape); + } else if (shape instanceof UPolygon) { + outPolygon((UPolygon) shape); + } else { + output.add("DEBUG " + shape.getClass().getSimpleName() + " " + dx + " " + dy); + output.add(""); + } + + } + + private void outPolygon(UPolygon shape) { + output.add("POLYGON:"); + output.add(" points:"); + for (Point2D pt : shape.getPoints()) { + final double xp = getTranslateX() + pt.getX(); + final double yp = getTranslateY() + pt.getY(); + output.add(" - " + pointd(xp, yp)); + } + output.add(" stroke: " + getParam().getStroke()); + output.add(" shadow: " + (int) shape.getDeltaShadow()); + output.add(" color: " + colorToString(getParam().getColor())); + output.add(" backcolor: " + colorToString(getParam().getBackcolor())); + output.add(""); + + } + + private void outText(UText shape) { + output.add("TEXT:"); + output.add(" text: " + shape.getText()); + output.add(" position: " + pointd(getTranslateX(), getTranslateY())); + output.add(" orientation: " + shape.getOrientation()); + output.add(" font: " + shape.getFontConfiguration().toStringDebug()); + output.add(" color: " + colorToString(getParam().getColor())); + output.add(""); + + } + + private void outRectangle(URectangle shape) { + output.add("RECTANGLE:"); + output.add(" pt1: " + pointd(getTranslateX(), getTranslateY())); + output.add(" pt2: " + pointd(getTranslateX() + shape.getWidth(), getTranslateY() + shape.getHeight())); + output.add(" xCorner: " + (int) shape.getRx()); + output.add(" yCorner: " + (int) shape.getRy()); + output.add(" stroke: " + getParam().getStroke()); + output.add(" shadow: " + (int) shape.getDeltaShadow()); + output.add(" color: " + colorToString(getParam().getColor())); + output.add(" backcolor: " + colorToString(getParam().getBackcolor())); + output.add(""); + + } + + private void outLine(ULine shape) { + output.add("LINE:"); + output.add(" pt1: " + pointd(getTranslateX(), getTranslateY())); + output.add(" pt2: " + pointd(getTranslateX() + shape.getDX(), getTranslateY() + shape.getDY())); + output.add(" stroke: " + getParam().getStroke()); + output.add(" shadow: " + (int) shape.getDeltaShadow()); + output.add(" color: " + colorToString(getParam().getColor())); + output.add(""); + + } + + private String point(int x, int y) { + return "" + x + ";" + y; + } + + private String pointd(double x, double y) { + return point((int) x, (int) y); + } + + private String colorToString(HColor color) { + if (color instanceof HColorSimple) { + final HColorSimple simple = (HColorSimple) color; + final Color internal = simple.getColor999(); + if (simple.isMonochrome()) { + return "monochrome " + Integer.toHexString(internal.getRGB()); + } + return Integer.toHexString(internal.getRGB()); + + } + return color.getClass().getSimpleName(); + } + + public void writeImageTOBEMOVED(OutputStream os, String metadata, int dpi) throws IOException { + print(os, "DPI: " + dpi); + print(os, ""); + + for (String s : output) { + print(os, s); + } + os.flush(); + } + + private void print(OutputStream os, String out) throws UnsupportedEncodingException, IOException { + os.write(out.getBytes("UTF-8")); + os.write("\n".getBytes("UTF-8")); + } + +} diff --git a/test/demo1/SimpleSequenceDiagramTest.java b/test/demo1/SimpleSequenceDiagramTest.java new file mode 100644 index 000000000..9afaa6f6d --- /dev/null +++ b/test/demo1/SimpleSequenceDiagramTest.java @@ -0,0 +1,168 @@ +package demo1; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.SourceStringReader; +import net.sourceforge.plantuml.core.DiagramDescription; + +/* + * This test is a simple POC of what could be non-regression test for PlantUML. + * + * In real world, test diagram and expected result would not be stored in source file. + */ +class SimpleSequenceDiagramTest { + + @Test + void testSimple() throws IOException { + + final String diagramText = getText(); + final SourceStringReader ssr = new SourceStringReader(diagramText, "UTF-8"); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final DiagramDescription diagramDescription = ssr.outputImage(baos, 0, new FileFormatOption(FileFormat.DEBUG)); + + assertEquals("(2 participants)", diagramDescription.getDescription()); + + final String desc = new String(baos.toByteArray(), "UTF-8"); + + final String expected = getExpectedResult(); + assertEquals(expected, desc); + + } + + private String getText() { + return packString( // + "@startuml", // + "Alice -> Bob : Hello", // + "@enduml"); + } + + private String getExpectedResult() { + return packString( // + "DPI: 96", // + "", // + "LINE:", // + " pt1: 29;41", // + " pt2: 29;91", // + " stroke: 5.0-5.0-1.0", // + " shadow: 0", // + " color: ffa80036", // + "", // + "LINE:", // + " pt1: 84;41", // + " pt2: 84;91", // + " stroke: 5.0-5.0-1.0", // + " shadow: 0", // + " color: ffa80036", // + "", // + "RECTANGLE:", // + " pt1: 5;5", // + " pt2: 49;36", // + " xCorner: 0", // + " yCorner: 0", // + " stroke: 0.0-0.0-1.5", // + " shadow: 4", // + " color: ffa80036", // + " backcolor: fffefece", // + "", // + "TEXT:", // + " text: Alice", // + " position: 12;22", // + " orientation: 0", // + " font: SansSerif.plain/14 []", // + " color: ffa80036", // + "", // + "RECTANGLE:", // + " pt1: 5;90", // + " pt2: 49;122", // + " xCorner: 0", // + " yCorner: 0", // + " stroke: 0.0-0.0-1.5", // + " shadow: 4", // + " color: ffa80036", // + " backcolor: fffefece", // + "", // + "TEXT:", // + " text: Alice", // + " position: 12;108", // + " orientation: 0", // + " font: SansSerif.plain/14 []", // + " color: ffa80036", // + "", // + "RECTANGLE:", // + " pt1: 63;5", // + " pt2: 102;36", // + " xCorner: 0", // + " yCorner: 0", // + " stroke: 0.0-0.0-1.5", // + " shadow: 4", // + " color: ffa80036", // + " backcolor: fffefece", // + "", // + "TEXT:", // + " text: Bob", // + " position: 70;22", // + " orientation: 0", // + " font: SansSerif.plain/14 []", // + " color: ffa80036", // + "", // + "RECTANGLE:", // + " pt1: 63;90", // + " pt2: 102;122", // + " xCorner: 0", // + " yCorner: 0", // + " stroke: 0.0-0.0-1.5", // + " shadow: 4", // + " color: ffa80036", // + " backcolor: fffefece", // + "", // + "TEXT:", // + " text: Bob", // + " position: 70;108", // + " orientation: 0", // + " font: SansSerif.plain/14 []", // + " color: ffa80036", // + "", // + "POLYGON:", // + " points:", // + " - 72;69", // + " - 82;73", // + " - 72;77", // + " - 76;73", // + " stroke: 0.0-0.0-1.0", // + " shadow: 0", // + " color: ffa80036", // + " backcolor: ffa80036", // + "", // + "LINE:", // + " pt1: 29;73", // + " pt2: 78;73", // + " stroke: 0.0-0.0-1.0", // + " shadow: 0", // + " color: ffa80036", // + "", // + "TEXT:", // + " text: Hello", // + " position: 36;65", // + " orientation: 0", // + " font: SansSerif.plain/13 []", // + " color: ffa80036"); + } + + private String packString(String... list) { + final StringBuilder sb = new StringBuilder(); + for (String s : list) { + sb.append(s); + sb.append("\n"); + } + return sb.toString() + "\n"; + } + +}