From 9c79c1256cd9991da5ab1ac3b6e168b9c5848068 Mon Sep 17 00:00:00 2001 From: Martin Ross Date: Wed, 16 Feb 2022 12:39:48 -0500 Subject: [PATCH 1/3] Add a new !pragma svginterface to control INTERACTIVE mode on SVG output --- .../plantuml/sudoku/GraphicsSudoku.java | 15 +++----- .../sourceforge/plantuml/svg/SvgGraphics.java | 13 ++++++- .../plantuml/ugraphic/FontChecker.java | 11 +++--- .../plantuml/ugraphic/ImageBuilder.java | 37 +++++-------------- .../plantuml/ugraphic/svg/UGraphicSvg.java | 5 ++- 5 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java index 1cc90e9ca..87ecca042 100644 --- a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java @@ -5,12 +5,12 @@ * (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 @@ -30,7 +30,7 @@ * * * Original Author: Arnaud Roques - * + * * */ package net.sourceforge.plantuml.sudoku; @@ -43,10 +43,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.EmptyImageBuilder; -import net.sourceforge.plantuml.FileFormat; -import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.*; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.Display; @@ -90,7 +87,7 @@ public class GraphicsSudoku { public ImageData writeImageSvg(OutputStream os) throws IOException { final UGraphicSvg ug = new UGraphicSvg(HColorUtils.WHITE, true, new Dimension2DDouble(0, 0), new ColorMapperIdentity(), false, 1.0, null, null, 0, "none", FileFormat.SVG.getDefaultStringBounder(), - LengthAdjust.defaultValue()); + LengthAdjust.defaultValue(), new Pragma()); drawInternal(ug); ug.writeToStream(os, null, -1); // dpi param is not used return ImageDataSimple.ok(); diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index c1b7d6d87..d66bd4dff 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -62,6 +62,7 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import net.sourceforge.plantuml.Pragma; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.Document; @@ -129,7 +130,8 @@ public class SvgGraphics { private final boolean svgDimensionStyle; private final LengthAdjust lengthAdjust; - private final boolean INTERACTIVE = false; + private final Pragma pragma; + private final boolean INTERACTIVE; final protected void ensureVisible(double x, double y) { if (x > maxX) { @@ -141,7 +143,7 @@ public class SvgGraphics { } public SvgGraphics(String backcolor, boolean svgDimensionStyle, Dimension2D minDim, double scale, String hover, - long seed, String preserveAspectRatio, LengthAdjust lengthAdjust, DarkStrategy darkStrategy) { + long seed, String preserveAspectRatio, LengthAdjust lengthAdjust, DarkStrategy darkStrategy, Pragma pragma) { try { this.lengthAdjust = lengthAdjust; this.svgDimensionStyle = svgDimensionStyle; @@ -149,6 +151,7 @@ public class SvgGraphics { this.document = getDocument(); this.backcolor = backcolor; this.preserveAspectRatio = preserveAspectRatio; + this.pragma = pragma; ensureVisible(minDim.getWidth(), minDim.getHeight()); this.root = getRootNode(); @@ -164,6 +167,12 @@ public class SvgGraphics { if (hover != null) defs.appendChild(getPathHover(hover)); + if (!pragma.isDefine("svginteractive")) + INTERACTIVE = false; + else { + INTERACTIVE = Boolean.valueOf(pragma.getValue("svginteractive")); + } + if (INTERACTIVE) { final Element styles = getStylesForInteractiveMode(); if (styles != null) diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java index 0863e0b0f..14ed2ca71 100644 --- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java +++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java @@ -5,12 +5,12 @@ * (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 @@ -30,7 +30,7 @@ * * * Original Author: Arnaud Roques - * + * * */ package net.sourceforge.plantuml.ugraphic; @@ -54,6 +54,7 @@ import java.util.Set; import javax.xml.transform.TransformerException; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.security.SImageIO; @@ -159,7 +160,7 @@ public class FontChecker { private String getSvgImage(char c) throws IOException, TransformerException { final SvgGraphics svg = new SvgGraphics(null, true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none", - LengthAdjust.defaultValue(), DarkStrategy.IGNORE_DARK_COLOR); + LengthAdjust.defaultValue(), DarkStrategy.IGNORE_DARK_COLOR, new Pragma()); svg.setStrokeColor("black"); svg.svgImage(getBufferedImage(c), 0, 0); final ByteArrayOutputStream os = new ByteArrayOutputStream(); diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index fa18d6c14..90e7f6fd1 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -5,12 +5,12 @@ * (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 @@ -30,7 +30,7 @@ * * * Original Author: Matthew Leather - * + * * */ package net.sourceforge.plantuml.ugraphic; @@ -51,24 +51,7 @@ import java.util.Set; import javax.swing.ImageIcon; -import net.sourceforge.plantuml.AnimatedGifEncoder; -import net.sourceforge.plantuml.AnnotatedWorker; -import net.sourceforge.plantuml.CMapData; -import net.sourceforge.plantuml.ColorParam; -import net.sourceforge.plantuml.CornerParam; -import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.EmptyImageBuilder; -import net.sourceforge.plantuml.FileFormat; -import net.sourceforge.plantuml.FileFormatOption; -import net.sourceforge.plantuml.FileUtils; -import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.LineParam; -import net.sourceforge.plantuml.OptionFlags; -import net.sourceforge.plantuml.Scale; -import net.sourceforge.plantuml.SvgCharSizeHack; -import net.sourceforge.plantuml.TitledDiagram; -import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.UseStyle; +import net.sourceforge.plantuml.*; import net.sourceforge.plantuml.anim.AffineTransformation; import net.sourceforge.plantuml.anim.Animation; import net.sourceforge.plantuml.api.ImageDataComplex; @@ -272,7 +255,7 @@ public class ImageBuilder { / 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, titledDiagram.getPragma()); maybeDrawBorder(ug, dim); if (randomPixel) { drawRandomPoint(ug); @@ -401,12 +384,12 @@ public class ImageBuilder { } private UGraphic createUGraphic(FileFormatOption option, final Dimension2D dim, Animation animationArg, double dx, - double dy, double scaleFactor) { + double dy, double scaleFactor, Pragma pragma) { switch (option.getFileFormat()) { case PNG: return createUGraphicPNG(scaleFactor, dim, animationArg, dx, dy, option.getWatermark()); case SVG: - return createUGraphicSVG(scaleFactor, dim); + return createUGraphicSVG(scaleFactor, dim, pragma); case EPS: return new UGraphicEps(backcolor, colorMapper, stringBounder, EpsStrategy.getDefault2()); case EPS_TEXT: @@ -432,14 +415,14 @@ public class ImageBuilder { } } - private UGraphic createUGraphicSVG(double scaleFactor, Dimension2D dim) { + private UGraphic createUGraphicSVG(double scaleFactor, Dimension2D dim, Pragma pragma) { final String hoverPathColorRGB = getHoverPathColorRGB(); final LengthAdjust lengthAdjust = skinParam == null ? LengthAdjust.defaultValue() : skinParam.getlengthAdjust(); final String preserveAspectRatio = getPreserveAspectRatio(); final boolean svgDimensionStyle = skinParam == null || skinParam.svgDimensionStyle(); final String svgLinkTarget = getSvgLinkTarget(); final UGraphicSvg ug = new UGraphicSvg(backcolor, svgDimensionStyle, dim, colorMapper, false, scaleFactor, - svgLinkTarget, hoverPathColorRGB, seed, preserveAspectRatio, stringBounder, lengthAdjust); + svgLinkTarget, hoverPathColorRGB, seed, preserveAspectRatio, stringBounder, lengthAdjust, pragma); return ug; } diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index a594404d5..4a98bcdd5 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -41,6 +41,7 @@ import java.util.Map; import javax.xml.transform.TransformerException; +import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.posimo.DotPath; @@ -89,10 +90,10 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo public UGraphicSvg(HColor defaultBackground, boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio, - StringBounder stringBounder, LengthAdjust lengthAdjust) { + StringBounder stringBounder, LengthAdjust lengthAdjust, Pragma pragma) { this(defaultBackground, minDim, colorMapper, new SvgGraphics(colorMapper.toSvg(defaultBackground), svgDimensionStyle, minDim, scale, hover, seed, - preserveAspectRatio, lengthAdjust, DarkStrategy.IGNORE_DARK_COLOR), + preserveAspectRatio, lengthAdjust, DarkStrategy.IGNORE_DARK_COLOR, pragma), textAsPath, linkTarget, stringBounder); if (defaultBackground instanceof HColorGradient) { final SvgGraphics svg = getGraphicObject(); From 61b0f7b1385e14851486ec0dc4d0cc43e78697a1 Mon Sep 17 00:00:00 2001 From: Martin Ross Date: Wed, 16 Feb 2022 13:31:48 -0500 Subject: [PATCH 2/3] Add support for interactive mouseover/mouseout focus on SVG to focusing on a node and its edges in a complex diagram. This is enabled with !pragma svginteractive. --- .../sourceforge/plantuml/svg/SvgGraphics.java | 26 ++++++ .../plantuml/ugraphic/ImageBuilder.java | 2 +- .../plantuml/ugraphic/svg/UGraphicSvg.java | 15 +++- svg/onmouseinteractivefooter.css | 6 ++ svg/onmouseinteractivefooter.js | 84 +++++++++++++++++++ 5 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 svg/onmouseinteractivefooter.css create mode 100644 svg/onmouseinteractivefooter.js diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index d66bd4dff..c5785d7e7 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -988,6 +988,7 @@ public class SvgGraphics { return SignatureUtils.getMD5Hex(comment); } + public void addComment(String comment) { final String signature = getMD5Hex(comment); comment = "MD5=[" + signature + "]\n" + comment; @@ -995,6 +996,31 @@ public class SvgGraphics { getG().appendChild(commentElement); } + public void addScriptTag(String url) { + final Element script = document.createElement("script"); + script.setAttribute("type", "text/javascript"); + script.setAttribute("xlink:href", url); + root.appendChild(script); + } + + public void addScript(String scriptTextPath) { + final Element script = document.createElement("script"); + final String scriptText = getData(scriptTextPath); + final CDATASection cDATAScript = document.createCDATASection(scriptText); + script.appendChild(cDATAScript); + root.appendChild(script); + } + + public void addStyle(String cssStylePath) { + final Element style = simpleElement("style"); + final String text = getData(cssStylePath); + + final CDATASection cdata = document.createCDATASection(text); + style.setAttribute("type", "text/css"); + style.appendChild(cdata); + root.appendChild(style); + } + public void openLink(String url, String title, String target) { Objects.requireNonNull(url); diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 90e7f6fd1..74fbb5b1e 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -255,7 +255,7 @@ public class ImageBuilder { / 96.0; if (scaleFactor <= 0) throw new IllegalStateException("Bad scaleFactor"); - UGraphic ug = createUGraphic(fileFormatOption, dim, animationArg, dx, dy, scaleFactor, titledDiagram.getPragma()); + UGraphic ug = createUGraphic(fileFormatOption, dim, animationArg, dx, dy, scaleFactor, titledDiagram !=null ? titledDiagram.getPragma() : new Pragma()); maybeDrawBorder(ug, dim); if (randomPixel) { drawRandomPoint(ug); diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index 4a98bcdd5..aa938242f 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -71,6 +71,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo private final boolean textAsPath2; private final String target; + private final Pragma pragma; public double dpiFactor() { return 1; @@ -85,6 +86,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo super(other); this.textAsPath2 = other.textAsPath2; this.target = other.target; + this.pragma = other.pragma; register(); } @@ -94,7 +96,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo this(defaultBackground, minDim, colorMapper, new SvgGraphics(colorMapper.toSvg(defaultBackground), svgDimensionStyle, minDim, scale, hover, seed, preserveAspectRatio, lengthAdjust, DarkStrategy.IGNORE_DARK_COLOR, pragma), - textAsPath, linkTarget, stringBounder); + textAsPath, linkTarget, stringBounder, pragma); if (defaultBackground instanceof HColorGradient) { final SvgGraphics svg = getGraphicObject(); svg.paintBackcolorGradient(colorMapper, (HColorGradient) defaultBackground); @@ -117,10 +119,11 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo } private UGraphicSvg(HColor defaultBackground, Dimension2D minDim, ColorMapper colorMapper, SvgGraphics svg, - boolean textAsPath, String linkTarget, StringBounder stringBounder) { + boolean textAsPath, String linkTarget, StringBounder stringBounder, Pragma pragma) { super(defaultBackground, colorMapper, stringBounder, svg); this.textAsPath2 = textAsPath; this.target = linkTarget; + this.pragma = pragma; register(); } @@ -152,6 +155,14 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo if (metadata != null) getGraphicObject().addComment(metadata); + if (pragma.isDefine("svginteractive") && Boolean.valueOf(pragma.getValue("svginteractive"))) { + // For performance reasons and also because we want the entire graph DOM to be create so we can register + // the event handlers on them we will append to the end of the document + getGraphicObject().addStyle("onmouseinteractivefooter.css"); + getGraphicObject().addScriptTag("https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"); + getGraphicObject().addScript("onmouseinteractivefooter.js"); + } + getGraphicObject().createXml(os); } catch (TransformerException e) { throw new IOException(e.toString()); diff --git a/svg/onmouseinteractivefooter.css b/svg/onmouseinteractivefooter.css new file mode 100644 index 000000000..0cddf4a8c --- /dev/null +++ b/svg/onmouseinteractivefooter.css @@ -0,0 +1,6 @@ +[data-mouse-over-selected="false"] { + opacity: 0.2; +} +[data-mouse-over-selected="true"] { + opacity: 1.0; +} \ No newline at end of file diff --git a/svg/onmouseinteractivefooter.js b/svg/onmouseinteractivefooter.js new file mode 100644 index 000000000..0389c370c --- /dev/null +++ b/svg/onmouseinteractivefooter.js @@ -0,0 +1,84 @@ +(function (){ + /** + * @param {SVG.G} node + * @param {SVG.G} topG + * @return {{node: Set, edges:Set}} + */ + function getEdgesAndDistance1Nodes(node, topG) { + const nodeName = node.attr("id").match(/elem_(.+)/)[1]; + const selector = "[id^=link_]" + const candidates = topG.find(selector) + let edges = new Set(); + let nodes = new Set(); + for (let link of candidates) { + const res = link.attr("id").match(/link_([A-Za-z\d]+)_([A-Za-z\d]+)/); + if (res && res.length==3) { + const N1 = res[1]; + const N2 = res[2]; + if (N1==nodeName) { + const N2selector = `[id^=elem_${N2}]`; + nodes.add(topG.findOne(N2selector)); + edges.add(link); + } else if (N2==nodeName) { + const N1selector = `[id^=elem_${N1}]`; + nodes.add(topG.findOne(N1selector)); + edges.add(link); + } + } + } + return { + "nodes" : nodes, + "edges" : edges + }; + } + + /** + * @param {SVG.G} node + * @param {function(SVG.Dom)} + * @return {{node: Set, edges:Set}} + */ + function walk(node, func) { + let children = node.children(); + for (let child of children) { + walk(child, func) + } + func(node); + } + let s = SVG("svg > g") + /** + * @param {SVGElement} domEl + * @return {{SVGElement}} + */ + function findEnclosingG(domEl) { + let curEl = domEl; + while (curEl.nodeName != "g") { + curEl = curEl.parentElement; + } + return curEl; + } + function onMouseOverElem(domEl) { + let e = SVG(findEnclosingG(domEl.target)); + walk(s, + e => { if (SVG(e)!=s) + SVG(e).attr('data-mouse-over-selected',"false"); + }); + walk(e, e => SVG(e).attr('data-mouse-over-selected',"true")); + let {nodes, edges} = getEdgesAndDistance1Nodes(SVG(e), s); + for (let node of nodes) { + walk(node, e => SVG(e).attr('data-mouse-over-selected',"true")); + } + for (let edge of edges) { + walk(edge, e => SVG(e).attr('data-mouse-over-selected',"true")); + } + } + + function onMouseOutElem(domEl) { + let e = SVG(findEnclosingG(domEl.target)); + walk(s, e => e.attr('data-mouse-over-selected',null)); + } + let gs = s.find("g[id^=elem_]"); + for (let g of gs) { + g.on("mouseover", onMouseOverElem); + g.on("mouseout", onMouseOutElem); + } +})(); From 6d0f6302ef06d454479439cb9f330ea9ba36a888 Mon Sep 17 00:00:00 2001 From: Martin Ross Date: Wed, 16 Feb 2022 16:18:55 -0500 Subject: [PATCH 3/3] Remove imports and push up Pragma to higher in call chain --- .../plantuml/sudoku/GraphicsSudoku.java | 7 ++-- .../sourceforge/plantuml/svg/SvgGraphics.java | 12 ++----- .../plantuml/ugraphic/FontChecker.java | 3 +- .../plantuml/ugraphic/ImageBuilder.java | 32 ++++++++++++++++--- .../plantuml/ugraphic/svg/UGraphicSvg.java | 17 +++++----- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java index 87ecca042..df9f7dca2 100644 --- a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java @@ -43,7 +43,10 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.*; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.Display; @@ -87,7 +90,7 @@ public class GraphicsSudoku { public ImageData writeImageSvg(OutputStream os) throws IOException { final UGraphicSvg ug = new UGraphicSvg(HColorUtils.WHITE, true, new Dimension2DDouble(0, 0), new ColorMapperIdentity(), false, 1.0, null, null, 0, "none", FileFormat.SVG.getDefaultStringBounder(), - LengthAdjust.defaultValue(), new Pragma()); + LengthAdjust.defaultValue(), false); drawInternal(ug); ug.writeToStream(os, null, -1); // dpi param is not used return ImageDataSimple.ok(); diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index c5785d7e7..85dc34dbd 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -62,7 +62,6 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import net.sourceforge.plantuml.Pragma; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.Document; @@ -130,7 +129,6 @@ public class SvgGraphics { private final boolean svgDimensionStyle; private final LengthAdjust lengthAdjust; - private final Pragma pragma; private final boolean INTERACTIVE; final protected void ensureVisible(double x, double y) { @@ -143,7 +141,7 @@ public class SvgGraphics { } public SvgGraphics(String backcolor, boolean svgDimensionStyle, Dimension2D minDim, double scale, String hover, - long seed, String preserveAspectRatio, LengthAdjust lengthAdjust, DarkStrategy darkStrategy, Pragma pragma) { + long seed, String preserveAspectRatio, LengthAdjust lengthAdjust, DarkStrategy darkStrategy, boolean interactive) { try { this.lengthAdjust = lengthAdjust; this.svgDimensionStyle = svgDimensionStyle; @@ -151,7 +149,7 @@ public class SvgGraphics { this.document = getDocument(); this.backcolor = backcolor; this.preserveAspectRatio = preserveAspectRatio; - this.pragma = pragma; + this.INTERACTIVE = interactive; ensureVisible(minDim.getWidth(), minDim.getHeight()); this.root = getRootNode(); @@ -167,12 +165,6 @@ public class SvgGraphics { if (hover != null) defs.appendChild(getPathHover(hover)); - if (!pragma.isDefine("svginteractive")) - INTERACTIVE = false; - else { - INTERACTIVE = Boolean.valueOf(pragma.getValue("svginteractive")); - } - if (INTERACTIVE) { final Element styles = getStylesForInteractiveMode(); if (styles != null) diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java index 14ed2ca71..840ef4eda 100644 --- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java +++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java @@ -54,7 +54,6 @@ import java.util.Set; import javax.xml.transform.TransformerException; import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.security.SImageIO; @@ -160,7 +159,7 @@ public class FontChecker { private String getSvgImage(char c) throws IOException, TransformerException { final SvgGraphics svg = new SvgGraphics(null, true, new Dimension2DDouble(0, 0), 1.0, null, 42, "none", - LengthAdjust.defaultValue(), DarkStrategy.IGNORE_DARK_COLOR, new Pragma()); + LengthAdjust.defaultValue(), DarkStrategy.IGNORE_DARK_COLOR, false); svg.setStrokeColor("black"); svg.svgImage(getBufferedImage(c), 0, 0); final ByteArrayOutputStream os = new ByteArrayOutputStream(); diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 74fbb5b1e..de4b0768a 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -51,7 +51,25 @@ import java.util.Set; import javax.swing.ImageIcon; -import net.sourceforge.plantuml.*; +import net.sourceforge.plantuml.AnimatedGifEncoder; +import net.sourceforge.plantuml.AnnotatedWorker; +import net.sourceforge.plantuml.CMapData; +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.CornerParam; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.LineParam; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.Scale; +import net.sourceforge.plantuml.SvgCharSizeHack; +import net.sourceforge.plantuml.Pragma; +import net.sourceforge.plantuml.TitledDiagram; +import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.UseStyle; import net.sourceforge.plantuml.anim.AffineTransformation; import net.sourceforge.plantuml.anim.Animation; import net.sourceforge.plantuml.api.ImageDataComplex; @@ -389,7 +407,13 @@ public class ImageBuilder { case PNG: return createUGraphicPNG(scaleFactor, dim, animationArg, dx, dy, option.getWatermark()); case SVG: - return createUGraphicSVG(scaleFactor, dim, pragma); + final boolean interactive; + if (!pragma.isDefine("svginteractive")) + interactive = false; + else { + interactive = Boolean.valueOf(pragma.getValue("svginteractive")); + } + return createUGraphicSVG(scaleFactor, dim, interactive); case EPS: return new UGraphicEps(backcolor, colorMapper, stringBounder, EpsStrategy.getDefault2()); case EPS_TEXT: @@ -415,14 +439,14 @@ public class ImageBuilder { } } - private UGraphic createUGraphicSVG(double scaleFactor, Dimension2D dim, Pragma pragma) { + private UGraphic createUGraphicSVG(double scaleFactor, Dimension2D dim, boolean interactive) { final String hoverPathColorRGB = getHoverPathColorRGB(); final LengthAdjust lengthAdjust = skinParam == null ? LengthAdjust.defaultValue() : skinParam.getlengthAdjust(); final String preserveAspectRatio = getPreserveAspectRatio(); final boolean svgDimensionStyle = skinParam == null || skinParam.svgDimensionStyle(); final String svgLinkTarget = getSvgLinkTarget(); final UGraphicSvg ug = new UGraphicSvg(backcolor, svgDimensionStyle, dim, colorMapper, false, scaleFactor, - svgLinkTarget, hoverPathColorRGB, seed, preserveAspectRatio, stringBounder, lengthAdjust, pragma); + svgLinkTarget, hoverPathColorRGB, seed, preserveAspectRatio, stringBounder, lengthAdjust, interactive); return ug; } diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index aa938242f..c30609995 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -41,7 +41,6 @@ import java.util.Map; import javax.xml.transform.TransformerException; -import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.posimo.DotPath; @@ -71,7 +70,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo private final boolean textAsPath2; private final String target; - private final Pragma pragma; + private final boolean interactive; public double dpiFactor() { return 1; @@ -86,17 +85,17 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo super(other); this.textAsPath2 = other.textAsPath2; this.target = other.target; - this.pragma = other.pragma; + this.interactive = other.interactive; register(); } public UGraphicSvg(HColor defaultBackground, boolean svgDimensionStyle, Dimension2D minDim, ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget, String hover, long seed, String preserveAspectRatio, - StringBounder stringBounder, LengthAdjust lengthAdjust, Pragma pragma) { + StringBounder stringBounder, LengthAdjust lengthAdjust, boolean interactive) { this(defaultBackground, minDim, colorMapper, new SvgGraphics(colorMapper.toSvg(defaultBackground), svgDimensionStyle, minDim, scale, hover, seed, - preserveAspectRatio, lengthAdjust, DarkStrategy.IGNORE_DARK_COLOR, pragma), - textAsPath, linkTarget, stringBounder, pragma); + preserveAspectRatio, lengthAdjust, DarkStrategy.IGNORE_DARK_COLOR, interactive), + textAsPath, linkTarget, stringBounder, interactive); if (defaultBackground instanceof HColorGradient) { final SvgGraphics svg = getGraphicObject(); svg.paintBackcolorGradient(colorMapper, (HColorGradient) defaultBackground); @@ -119,11 +118,11 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo } private UGraphicSvg(HColor defaultBackground, Dimension2D minDim, ColorMapper colorMapper, SvgGraphics svg, - boolean textAsPath, String linkTarget, StringBounder stringBounder, Pragma pragma) { + boolean textAsPath, String linkTarget, StringBounder stringBounder, boolean interactive) { super(defaultBackground, colorMapper, stringBounder, svg); this.textAsPath2 = textAsPath; this.target = linkTarget; - this.pragma = pragma; + this.interactive = interactive; register(); } @@ -155,7 +154,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo if (metadata != null) getGraphicObject().addComment(metadata); - if (pragma.isDefine("svginteractive") && Boolean.valueOf(pragma.getValue("svginteractive"))) { + if (interactive) { // For performance reasons and also because we want the entire graph DOM to be create so we can register // the event handlers on them we will append to the end of the document getGraphicObject().addStyle("onmouseinteractivefooter.css");