diff --git a/graphviz-test-example/ex1.png b/graphviz-test-example/ex1.png index efac7fa..3eff98c 100644 Binary files a/graphviz-test-example/ex1.png and b/graphviz-test-example/ex1.png differ diff --git a/graphviz-test-example/ex1i.png b/graphviz-test-example/ex1i.png index 59770c3..0aa242c 100644 Binary files a/graphviz-test-example/ex1i.png and b/graphviz-test-example/ex1i.png differ diff --git a/graphviz-test-example/ex1m.png b/graphviz-test-example/ex1m.png index 59770c3..0aa242c 100644 Binary files a/graphviz-test-example/ex1m.png and b/graphviz-test-example/ex1m.png differ diff --git a/graphviz-test-example/ex2.png b/graphviz-test-example/ex2.png index d214a77..ae24c27 100644 Binary files a/graphviz-test-example/ex2.png and b/graphviz-test-example/ex2.png differ diff --git a/graphviz-test-example/ex3.png b/graphviz-test-example/ex3.png index 8bcb451..e587475 100644 Binary files a/graphviz-test-example/ex3.png and b/graphviz-test-example/ex3.png differ diff --git a/graphviz-test-example/ex4-1.png b/graphviz-test-example/ex4-1.png index 1d8d432..b3af89d 100644 Binary files a/graphviz-test-example/ex4-1.png and b/graphviz-test-example/ex4-1.png differ diff --git a/graphviz-test-example/ex4-2.png b/graphviz-test-example/ex4-2.png index 269d435..fc49ac5 100644 Binary files a/graphviz-test-example/ex4-2.png and b/graphviz-test-example/ex4-2.png differ diff --git a/graphviz-test-example/ex5.svg b/graphviz-test-example/ex5.svg index accc987..b13bd1a 100644 --- a/graphviz-test-example/ex5.svg +++ b/graphviz-test-example/ex5.svg @@ -1,4 +1,4 @@ - example5 diff --git a/graphviz-test-example/ex5b.png b/graphviz-test-example/ex5b.png index 6c68b04..ce33075 100644 Binary files a/graphviz-test-example/ex5b.png and b/graphviz-test-example/ex5b.png differ diff --git a/graphviz-test-example/ex5p.pdf b/graphviz-test-example/ex5p.pdf index fb35b6b..4f9cc7c 100644 Binary files a/graphviz-test-example/ex5p.pdf and b/graphviz-test-example/ex5p.pdf differ diff --git a/graphviz-test-example/ex5s.png b/graphviz-test-example/ex5s.png index d142cd3..7d756c7 100644 Binary files a/graphviz-test-example/ex5s.png and b/graphviz-test-example/ex5s.png differ diff --git a/graphviz-test-example/ex6a.png b/graphviz-test-example/ex6a.png index 9f91401..9a022f2 100644 Binary files a/graphviz-test-example/ex6a.png and b/graphviz-test-example/ex6a.png differ diff --git a/graphviz-test-example/ex6d.png b/graphviz-test-example/ex6d.png index 9f91401..9a022f2 100644 Binary files a/graphviz-test-example/ex6d.png and b/graphviz-test-example/ex6d.png differ diff --git a/graphviz-test-example/ex7.png b/graphviz-test-example/ex7.png index 1e296d0..1e682ce 100644 Binary files a/graphviz-test-example/ex7.png and b/graphviz-test-example/ex7.png differ diff --git a/graphviz-test-example/ex8.png b/graphviz-test-example/ex8.png index c2d14de..1a1cca8 100644 Binary files a/graphviz-test-example/ex8.png and b/graphviz-test-example/ex8.png differ diff --git a/src/main/java/guru/nidi/graphviz/engine/Format.java b/src/main/java/guru/nidi/graphviz/engine/Format.java index 0e57185..ef8bacd 100644 --- a/src/main/java/guru/nidi/graphviz/engine/Format.java +++ b/src/main/java/guru/nidi/graphviz/engine/Format.java @@ -24,22 +24,37 @@ public enum Format { PNG("svg", "png", true, true) { @Override - EngineResult postProcess(EngineResult result, double fontAdjust) { - return result.mapString(s -> postProcessSvg(s, true, fontAdjust)); + String preProcess(String src) { + return encodeXml(super.preProcess(src)); + } + + @Override + EngineResult postProcess(Graphviz graphviz, EngineResult result) { + return result.mapString(s -> postProcessSvg(graphviz, s, true)); } }, SVG("svg", "svg", false, true) { @Override - EngineResult postProcess(EngineResult result, double fontAdjust) { - return result.mapString(s -> postProcessSvg(s, true, fontAdjust)); + String preProcess(String src) { + return encodeXml(super.preProcess(src)); + } + + @Override + EngineResult postProcess(Graphviz graphviz, EngineResult result) { + return result.mapString(s -> postProcessSvg(graphviz, s, true)); } }, SVG_STANDALONE("svg", "svg", false, true) { @Override - EngineResult postProcess(EngineResult result, double fontAdjust) { - return result.mapString(s -> postProcessSvg(s, false, fontAdjust)); + String preProcess(String src) { + return encodeXml(super.preProcess(src)); + } + + @Override + EngineResult postProcess(Graphviz graphviz, EngineResult result) { + return result.mapString(s -> postProcessSvg(graphviz, s, false)); } }, DOT("dot", "dot", false, false), @@ -57,9 +72,9 @@ EngineResult postProcess(EngineResult result, double fontAdjust) { "\\d+)(?p[tx])\" height=\"(?\\d+)p[tx]\"" + "(?.*?>\\R[0-9.]+) (?[0-9.]+)\\)", Pattern.DOTALL); - private static final double PIXEL_PER_POINT = 1.3333; + final String vizName; - final String fileExtension; + public final String fileExtension; final boolean image; final boolean svg; @@ -70,34 +85,70 @@ EngineResult postProcess(EngineResult result, double fontAdjust) { this.svg = svg; } - EngineResult postProcess(EngineResult result, double fontAdjust) { + String preProcess(String src) { + return replaceSubSpaces(src); + } + + EngineResult postProcess(Graphviz graphviz, EngineResult result) { return result; } - private static String postProcessSvg(String result, boolean prefix, double fontAdjust) { + private static String replaceSubSpaces(String src) { + final char[] chars = src.toCharArray(); + for (int i = 0; i < chars.length; i++) { + if (chars[i] < ' ' && chars[i] != '\t' && chars[i] != '\r' && chars[i] != '\n') { + chars[i] = ' '; + } + } + return new String(chars); + } + + private static String encodeXml(String src) { + return src.replace("&", "&"); + } + + private static String postProcessSvg(Graphviz graphviz, String result, boolean prefix) { final String unprefixed = prefix ? withoutPrefix(result) : result; - final String pixelSized = pointsToPixels(unprefixed); - return fontAdjust == 1 ? pixelSized : fontAdjusted(pixelSized, fontAdjust); + final String pixelSized = pointsToPixels(unprefixed, graphviz.dpi(), + graphviz.width, graphviz.height, graphviz.scale); + return graphviz.fontAdjust == 1 ? pixelSized : fontAdjusted(pixelSized, graphviz.fontAdjust); + } + + private static String withoutPrefix(String svg) { + final int pos = svg.indexOf(" 0 && height > 0) { + w = width; + h = height; + } else if (width > 0) { + h *= width / w; + w = width; + } else if (height > 0) { + w *= height / h; + h = height; } - final double scaleX = Double.parseDouble(m.group("scaleX")) / PIXEL_PER_POINT; - final double scaleY = Double.parseDouble(m.group("scaleY")) / PIXEL_PER_POINT; - return m.replaceFirst(" engineQueue; @Nullable @@ -62,7 +57,8 @@ private Graphviz(String src, @Nullable Rasterizer rasterizer, } public static void useDefaultEngines() { - useEngine(new GraphvizCmdLineEngine(), new GraphvizServerEngine(), new GraphvizJdkEngine()); + useEngine(new GraphvizCmdLineEngine(), + new GraphvizServerEngine(), new GraphvizJdkEngine()); } public static void useEngine(GraphvizEngine first, GraphvizEngine... rest) { @@ -134,13 +130,9 @@ public static void releaseEngine() { engineQueue = null; } - public static Graphviz fromString(String src) { - return new Graphviz(src, Rasterizer.DEFAULT, 0, 0, 1, 1, Options.create()); - } - public static Graphviz fromFile(File src) throws IOException { try (final InputStream in = new FileInputStream(src)) { - return fromString(readStream(in)).basedir(src.getParentFile()); + return fromString(readStream(in)).basedir(src.getAbsoluteFile().getParentFile()); } } @@ -149,20 +141,11 @@ public static Graphviz fromGraph(Graph graph) { } public static Graphviz fromGraph(MutableGraph graph) { - return withDefaultDpi(graph, g -> fromString(g.toString())); + return fromString(graph.toString()); } - private static T withDefaultDpi(MutableGraph graph, Function action) { - final MutableAttributed attrs = graph.graphAttrs(); - final Object oldDpi = attrs.get("dpi"); - if (oldDpi == null) { - attrs.add("dpi", 96); - } - try { - return action.apply(graph); - } finally { - attrs.add("dpi", oldDpi); - } + public static Graphviz fromString(String src) { + return new Graphviz(src, Rasterizer.DEFAULT, 0, 0, 1, 1, Options.create()); } public Graphviz engine(Engine engine) { @@ -215,14 +198,19 @@ public Renderer render(Format format) { EngineResult execute() { final EngineResult result = options.format == Format.DOT ? EngineResult.fromString(src) - : getEngine().execute(src, options, rasterizer); - return options.format.postProcess(result, fontAdjust); + : getEngine().execute(options.format.preProcess(src), options, rasterizer); + return options.format.postProcess(this, result); } Format format() { return options.format; } + double dpi() { + final Matcher matcher = DPI_PATTERN.matcher(src); + return matcher.find() ? Double.parseDouble(matcher.group(1)) : 72; + } + private static class ErrorGraphvizEngine implements GraphvizEngine { @Override public void init(Consumer onOk, Consumer onError) { diff --git a/src/main/java/guru/nidi/graphviz/engine/SalamanderRasterizer.java b/src/main/java/guru/nidi/graphviz/engine/SalamanderRasterizer.java index eda9d0f..f359122 100644 --- a/src/main/java/guru/nidi/graphviz/engine/SalamanderRasterizer.java +++ b/src/main/java/guru/nidi/graphviz/engine/SalamanderRasterizer.java @@ -30,27 +30,13 @@ class SalamanderRasterizer extends SvgRasterizer { @Override public BufferedImage doRasterize(Graphviz graphviz, @Nullable Consumer graphicsConfigurer, String svg) { final SVGDiagram diagram = createDiagram(svg); - double scaleX = graphviz.scale; - double scaleY = graphviz.scale; - if (graphviz.width != 0 || graphviz.height != 0) { - scaleX = graphviz.scale * graphviz.width / diagram.getWidth(); - scaleY = graphviz.scale * graphviz.height / diagram.getHeight(); - if (scaleX == 0) { - scaleX = scaleY; - } - if (scaleY == 0) { - scaleY = scaleX; - } - } - final int width = (int) Math.ceil(scaleX * diagram.getWidth()); - final int height = (int) Math.ceil(scaleY * diagram.getHeight()); - final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + final BufferedImage image = new BufferedImage( + (int) diagram.getWidth(), (int) diagram.getHeight(), BufferedImage.TYPE_INT_ARGB); final Graphics2D graphics = image.createGraphics(); configGraphics(graphics); if (graphicsConfigurer != null) { graphicsConfigurer.accept(graphics); } - graphics.scale(scaleX, scaleY); renderDiagram(diagram, graphics); return image; } diff --git a/src/main/java/guru/nidi/graphviz/model/ThrowingFunction.java b/src/main/java/guru/nidi/graphviz/model/ThrowingFunction.java index 690dc80..7777f0f 100644 --- a/src/main/java/guru/nidi/graphviz/model/ThrowingFunction.java +++ b/src/main/java/guru/nidi/graphviz/model/ThrowingFunction.java @@ -22,6 +22,8 @@ public interface ThrowingFunction { default R applyNotThrowing(T t) { try { return apply(t); + } catch (RuntimeException e) { + throw e; } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/contextmapper/contextmap/generator/ContextMapGenerator.java b/src/main/java/org/contextmapper/contextmap/generator/ContextMapGenerator.java index f235f90..fc2f279 100644 --- a/src/main/java/org/contextmapper/contextmap/generator/ContextMapGenerator.java +++ b/src/main/java/org/contextmapper/contextmap/generator/ContextMapGenerator.java @@ -47,8 +47,8 @@ public class ContextMapGenerator { private Map bcNodesMap; protected int labelSpacingFactor = 1; - protected int height = 1500; - protected int width = 3600; + protected int height = 1000; + protected int width = 2000; protected boolean useHeight = false; protected boolean useWidth = true; diff --git a/src/test/java/guru/nidi/graphviz/engine/FormatTest.java b/src/test/java/guru/nidi/graphviz/engine/FormatTest.java index 752ac84..3a798f5 100644 --- a/src/test/java/guru/nidi/graphviz/engine/FormatTest.java +++ b/src/test/java/guru/nidi/graphviz/engine/FormatTest.java @@ -48,8 +48,9 @@ class FormatTest { @ParameterizedTest @MethodSource void postProcess(Entry values) { - assertEquals(EngineResult.fromString(values.getValue()), - SVG.postProcess(EngineResult.fromString(START1_7 + values.getKey()), .5)); + assertEquals(EngineResult.fromString(values.getValue()), SVG.postProcess( + Graphviz.fromString("graph {dpi=96}").fontAdjust(.5), + EngineResult.fromString(START1_7 + values.getKey()))); } static Set> postProcess() { diff --git a/src/test/java/guru/nidi/graphviz/engine/GraphvizTest.java b/src/test/java/guru/nidi/graphviz/engine/GraphvizTest.java index 10b1839..518d124 100644 --- a/src/test/java/guru/nidi/graphviz/engine/GraphvizTest.java +++ b/src/test/java/guru/nidi/graphviz/engine/GraphvizTest.java @@ -64,7 +64,7 @@ void widthMethodChainCheck() { void executeWithTotalMemory() { final Graph graph = graph().with(node("a").link("b")); final String result = Graphviz.fromGraph(graph).totalMemory(32000).render(Format.SVG).toString(); - assertThat(result, is("totalMemory=32000;render('graph { graph [\"dpi\"=\"96\"] \"a\" -- \"b\" }'," + assertThat(result, is("totalMemory=32000;render('graph { \"a\" -- \"b\" }'," + "{format:'svg',engine:'dot',totalMemory:'32000',basedir:'" + new File(".").getAbsolutePath() + "',images:[]});")); } @@ -72,7 +72,7 @@ void executeWithTotalMemory() { void executeWithoutTotalMemory() { final Graph graph = graph().with(node("a").link("b")); final String result = Graphviz.fromGraph(graph).render(Format.SVG).toString(); - assertThat(result, is("render('graph { graph [\"dpi\"=\"96\"] \"a\" -- \"b\" }'," + assertThat(result, is("render('graph { \"a\" -- \"b\" }'," + "{format:'svg',engine:'dot',basedir:'" + new File(".").getAbsolutePath() + "',images:[]});")); } diff --git a/src/test/java/guru/nidi/graphviz/engine/OptionsTest.java b/src/test/java/guru/nidi/graphviz/engine/OptionsTest.java index 01bc71e..ba3d47e 100644 --- a/src/test/java/guru/nidi/graphviz/engine/OptionsTest.java +++ b/src/test/java/guru/nidi/graphviz/engine/OptionsTest.java @@ -43,6 +43,23 @@ void fromJsonEmptyImages() { assertEquals(expected, options); } + @Test + void fromJsonOneImage() { + final Options options = Options.fromJson("{engine:'DOT',format:'PNG',images:[" + + "{path:'" + uriPathOf(new File("./graphviz-test-example/ex1.png")) + "',width:'550px',height:'100px'}]}"); + final Options expected = Options.create().engine(Engine.DOT).format(Format.PNG).image("graphviz-test-example/ex1.png"); + assertEquals(expected, options); + } + + @Test + void fromJsonTwoImages() { + final Options options = Options.fromJson("{engine:'DOT',format:'PNG',images:[" + + "{path:'" + uriPathOf(new File("./graphviz-test-example/ex1.png")) + "',width:'550px',height:'100px'}," + + "{path:'" + uriPathOf(new File("./graphviz-test-example/ex2.png")) + "',width:'900px',height:'964px']}"); + final Options expected = Options.create().engine(Engine.DOT).format(Format.PNG).image("graphviz-test-example/ex1.png").image("graphviz-test-example/ex2.png"); + assertEquals(expected, options); + } + @Test void toJsonMinimal() { final String s = Options.create().engine(Engine.DOT).format(Format.PNG).toJson(false); @@ -60,7 +77,15 @@ void toJsonEmptyImages() { void toJsonOneImage() { final String s = Options.create().engine(Engine.DOT).format(Format.PNG).basedir(new File("graphviz-test-example")).image("ex1.png").toJson(false); assertEquals("{format:'svg',engine:'dot',basedir:'" + new File("graphviz-test-example").getAbsolutePath() + "',images:[" + - "{path:'" + uriPathOf(new File("graphviz-test-example/ex1.png")) + "',width:'548px',height:'100px'}]}", s); + "{path:'" + uriPathOf(new File("graphviz-test-example/ex1.png")) + "',width:'550px',height:'100px'}]}", s); + } + + @Test + void toJsonTwoImages() { + final String s = Options.create().engine(Engine.DOT).format(Format.PNG).basedir(new File("graphviz-test-example")).image("ex1.png").image("ex2.png").toJson(false); + assertEquals("{format:'svg',engine:'dot',basedir:'" + new File("graphviz-test-example").getAbsolutePath() + "',images:[" + + "{path:'" + uriPathOf(new File("graphviz-test-example/ex1.png")) + "',width:'550px',height:'100px'}," + + "{path:'" + uriPathOf(new File("graphviz-test-example/ex2.png")) + "',width:'900px',height:'964px'}]}", s); } } diff --git a/src/test/java/guru/nidi/graphviz/engine/RendererTest.java b/src/test/java/guru/nidi/graphviz/engine/RendererTest.java index dd77ac4..1c52f5b 100644 --- a/src/test/java/guru/nidi/graphviz/engine/RendererTest.java +++ b/src/test/java/guru/nidi/graphviz/engine/RendererTest.java @@ -76,7 +76,7 @@ void image() throws IOException { final File out = new File("target/image.png"); final Graphviz g = Graphviz.fromGraph(graph().with(node(" ").with(Image.of("graphviz.png")))); g.basedir(new File("graphviz-test-example")).render(Format.PNG).toFile(out); - assertThat((int) out.length(), greaterThan(20000)); + assertThat((int) out.length(), greaterThan(19000)); } @Test diff --git a/src/test/java/org/contextmapper/contextmap/generator/ContextMapGeneratorTest.java b/src/test/java/org/contextmapper/contextmap/generator/ContextMapGeneratorTest.java index 28f5238..6f83206 100644 --- a/src/test/java/org/contextmapper/contextmap/generator/ContextMapGeneratorTest.java +++ b/src/test/java/org/contextmapper/contextmap/generator/ContextMapGeneratorTest.java @@ -63,7 +63,7 @@ public void canGenerateContextMapByOutputstream() throws IOException { assertFalse(new File(CONTEXT_MAP_FILE).exists()); OutputStream outputStream = new FileOutputStream(new File(CONTEXT_MAP_FILE)); generator.setLabelSpacingFactor(10) - .setWidth(3600) + .setWidth(2000) .generateContextMapGraphic(createTestContextMap(), Format.PNG, outputStream); outputStream.close(); @@ -79,7 +79,7 @@ public void canGenerateContextMapWithFixedWith() throws IOException { // when assertFalse(new File(CONTEXT_MAP_FILE_FIXED_WIDTH).exists()); generator.setLabelSpacingFactor(10) - .setWidth(3600) + .setWidth(2000) .generateContextMapGraphic(createTestContextMap(), Format.PNG, CONTEXT_MAP_FILE_FIXED_WIDTH); // then @@ -95,10 +95,10 @@ public void canGenerateContextMapWithFixedHeight() throws IOException { assertFalse(new File(CONTEXT_MAP_FILE_DOT_FORMAT).exists()); assertFalse(new File(CONTEXT_MAP_FILE_SVG_FORMAT).exists()); generator.setLabelSpacingFactor(10) - .setHeight(3600) + .setHeight(2000) .generateContextMapGraphic(createTestContextMap(), Format.DOT, CONTEXT_MAP_FILE_DOT_FORMAT); generator.setLabelSpacingFactor(10) - .setHeight(3600) + .setHeight(2000) .generateContextMapGraphic(createTestContextMap(), Format.SVG, CONTEXT_MAP_FILE_SVG_FORMAT); // then @@ -114,7 +114,7 @@ public void canGenerateInOtherFormatsThenPNG() throws IOException { // when assertFalse(new File(CONTEXT_MAP_FILE_FIXED_HEIGHT).exists()); generator.setLabelSpacingFactor(10) - .setWidth(3600) + .setWidth(2000) .generateContextMapGraphic(createTestContextMap(), Format.PNG, CONTEXT_MAP_FILE_FIXED_HEIGHT); // then