Skip to content

Commit

Permalink
#393, #400, #399, #398, #396 Migrated to EchoSVG
Browse files Browse the repository at this point in the history
  • Loading branch information
krasa committed Aug 25, 2023
1 parent 736fbdb commit 825e10a
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 157 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@

## [Unreleased]

- Rendering exception fix
## [7.0.0-IJ2023.2] - 2023-08-25

- SVG rendering migrated to EchoSVG from Batik
- PlantUML library upgrade to v1.2023.10

[Unreleased]: https://github.com/esteinberg/plantuml4idea/compare/v7.0.0-IJ2023.2...HEAD

[7.0.0-IJ2023.2]: https://github.com/esteinberg/plantuml4idea/commits/v7.0.0-IJ2023.2
20 changes: 5 additions & 15 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,19 @@ java.sourceSets["main"].java {
// Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog
dependencies {
// https://mvnrepository.com/artifact/net.sourceforge.plantuml/plantuml
implementation("net.sourceforge.plantuml:plantuml:1.2023.9")
implementation("net.sourceforge.plantuml:plantuml:1.2023.10")

testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation("org.junit.jupiter:junit-jupiter")

implementation("org.jetbrains.intellij.deps.batik:batik-transcoder:1.16.0-32") {
exclude(group = "it.unimi.dsi", module = "fastutil")
// exclude(group = "xml-apis", module = "xml-apis")
implementation("io.sf.carte:echosvg-all:0.3.3") {
// exclude(group = "it.unimi.dsi", module = "fastutil")
exclude(group = "xml-apis", module = "xml-apis")
// exclude(group = "xml-apis", module = "xml-apis-ext")
exclude(group = "commons-io", module = "commons-io")
exclude(group = "commons-logging", module = "commons-logging")
}

// implementation("io.sf.carte:echosvg-all:0.3")

// 2.7.3 breaks org.plantuml.idea.rendering.ImageItem.parseLinks
implementation("xalan:xalan:2.7.0")


// https://mvnrepository.com/artifact/xerces/xercesImpl
implementation("xerces:xercesImpl:2.12.2")
// https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE
implementation("net.sf.saxon:Saxon-HE:12.2")

}

Expand Down Expand Up @@ -157,7 +147,7 @@ tasks {
}

publishPlugin {
// dependsOn("patchChangelog")
dependsOn("patchChangelog")
token = environment("PUBLISH_TOKEN")
// The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
// Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pluginName=plantuml4idea
pluginRepositoryUrl=https://github.com/esteinberg/plantuml4idea

# SemVer format -> https://semver.org
pluginVersion=6.3.1-IJ2023.2
pluginVersion=7.0.0-IJ2023.2

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild=232.6734.9
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
Expand Down Expand Up @@ -227,9 +225,7 @@ public synchronized void createImage(Component component, double zoom) {
throw new RuntimeException("Empty file");
}

ByteArrayInputStream in = new ByteArrayInputStream(buf);
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
Document svgDocument = MySvgDocumentFactoryKt.createSvgDocument(null, reader);
Document svgDocument = MySvgDocumentFactoryKt.createSvgDocument(null, buf);
logDocument(svgDocument);

//it shows what is in png document - unZOOMED values, not limited by px limit
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.plantuml.idea.preview.image.svg.batik

import org.apache.batik.anim.dom.SVG12DOMImplementation
import org.apache.batik.anim.dom.SVGDOMImplementation
import org.apache.batik.anim.dom.SVGOMDocument
import org.apache.batik.dom.GenericCDATASection
import org.apache.batik.dom.GenericText
import org.apache.batik.transcoder.TranscoderException
import org.apache.batik.util.ParsedURL
import com.intellij.util.xml.dom.createXmlStreamReader
import io.sf.carte.echosvg.anim.dom.SVG12DOMImplementation
import io.sf.carte.echosvg.anim.dom.SVGDOMImplementation
import io.sf.carte.echosvg.anim.dom.SVGOMDocument
import io.sf.carte.echosvg.dom.GenericCDATASection
import io.sf.carte.echosvg.dom.GenericText
import io.sf.carte.echosvg.transcoder.TranscoderException
import io.sf.carte.echosvg.util.ParsedURL
import org.codehaus.stax2.XMLStreamReader2
import org.jetbrains.annotations.ApiStatus
import org.w3c.dom.Document
import org.w3c.dom.Element
import org.w3c.dom.Node
import java.io.Reader
import java.io.InputStream
import javax.xml.stream.XMLStreamConstants
import javax.xml.stream.XMLStreamException
import javax.xml.stream.XMLStreamReader

@ApiStatus.Internal
fun createSvgDocument(uri: String?, reader: Reader): Document {
val result = reader.use {
val xmlStreamReader = MyJDOMUtil.getXmlInputFactory().createXMLStreamReader(reader)
try {
buildDocument(xmlStreamReader)
} catch (e: XMLStreamException) {
throw TranscoderException(e)
} finally {
xmlStreamReader.close()
}
fun createSvgDocument(uri: String?, reader: InputStream) = createSvgDocument(uri, createXmlStreamReader(reader))

@ApiStatus.Internal
fun createSvgDocument(uri: String?, data: ByteArray) = createSvgDocument(uri, createXmlStreamReader(data))

private fun createSvgDocument(uri: String?, xmlStreamReader: XMLStreamReader2): Document {
val result = try {
buildDocument(xmlStreamReader)
} catch (e: XMLStreamException) {
throw TranscoderException(e)
} finally {
xmlStreamReader.close()
}

if (uri != null) {
Expand All @@ -36,7 +40,6 @@ fun createSvgDocument(uri: String?, reader: Reader): Document {
}
return result
}

private fun buildDocument(reader: XMLStreamReader): SVGOMDocument {
var state = reader.eventType
if (XMLStreamConstants.START_DOCUMENT != state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ package org.plantuml.idea.preview.image.svg.batik

import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.ImageLoader
import org.apache.batik.anim.dom.SVGOMDocument
import org.apache.batik.bridge.*
import org.apache.batik.bridge.svg12.SVG12BridgeContext
import org.apache.batik.ext.awt.RenderingHintsKeyExt
import org.apache.batik.gvt.CanvasGraphicsNode
import org.apache.batik.gvt.CompositeGraphicsNode
import org.apache.batik.gvt.GraphicsNode
import org.apache.batik.transcoder.TranscoderException
import org.apache.batik.util.ParsedURL
import org.apache.batik.util.SVGConstants
import org.apache.batik.util.SVGFeatureStrings
import io.sf.carte.echosvg.anim.dom.SVGOMDocument
import io.sf.carte.echosvg.bridge.*
import io.sf.carte.echosvg.bridge.svg12.SVG12BridgeContext
import io.sf.carte.echosvg.ext.awt.RenderingHintsKeyExt
import io.sf.carte.echosvg.ext.awt.image.codec.imageio.ImageIOJPEGRegistryEntry
import io.sf.carte.echosvg.ext.awt.image.codec.imageio.ImageIOPNGRegistryEntry
import io.sf.carte.echosvg.ext.awt.image.codec.imageio.ImageIOTIFFRegistryEntry
import io.sf.carte.echosvg.ext.awt.image.codec.png.PNGRegistryEntry
import io.sf.carte.echosvg.ext.awt.image.spi.ImageTagRegistry
import io.sf.carte.echosvg.gvt.CanvasGraphicsNode
import io.sf.carte.echosvg.gvt.CompositeGraphicsNode
import io.sf.carte.echosvg.gvt.GraphicsNode
import io.sf.carte.echosvg.transcoder.TranscoderException
import io.sf.carte.echosvg.util.ParsedURL
import io.sf.carte.echosvg.util.SVGConstants
import io.sf.carte.echosvg.util.SVGFeatureStrings
import org.jetbrains.annotations.ApiStatus
import org.plantuml.idea.settings.PlantUmlSettings
import org.w3c.dom.Document
Expand All @@ -25,11 +30,11 @@ import org.w3c.dom.svg.SVGDocument
import java.awt.*
import java.awt.geom.AffineTransform
import java.awt.image.BufferedImage
import java.io.StringReader
import java.lang.ref.WeakReference
import kotlin.math.max
import kotlin.math.min


private fun logger() = Logger.getInstance(MySvgTranscoder::class.java)

private val identityTransform = AffineTransform()
Expand All @@ -39,6 +44,12 @@ private val supportedFeatures = HashSet<String>()
class MySvgTranscoder private constructor(private var width: Float, private var height: Float) : UserAgent {
companion object {
init {
val registry = ImageTagRegistry.getRegistry()
registry.register(PNGRegistryEntry())
registry.register(ImageIOTIFFRegistryEntry())
registry.register(ImageIOJPEGRegistryEntry())
registry.register(ImageIOPNGRegistryEntry())

SVGFeatureStrings.addSupportedFeatureStrings(supportedFeatures)
}

Expand Down Expand Up @@ -151,7 +162,7 @@ class MySvgTranscoder private constructor(private var width: Float, private var
" <line x1=\"1\" y1=\"1\" x2=\"15\" y2=\"15\" stroke=\"red\" stroke-width=\"2\"/>\n" +
" <line x1=\"1\" y1=\"15\" x2=\"15\" y2=\"1\" stroke=\"red\" stroke-width=\"2\"/>\n" +
"</svg>\n"
return createSvgDocument(null, StringReader(fallbackIcon)) as SVGDocument
return createSvgDocument(null, fallbackIcon.toByteArray()) as SVGDocument
}

override fun getTransform() = currentTransform!!
Expand Down Expand Up @@ -188,7 +199,7 @@ class MySvgTranscoder private constructor(private var width: Float, private var

override fun getPixelUnitToMillimeter(): Float = 0.26458333333333333333333333333333f // 96dpi

override fun getPixelToMM() = pixelUnitToMillimeter
// override fun getPixelToMM() = pixelUnitToMillimeter

override fun getDefaultFontFamily() = "Arial, Helvetica, sans-serif"

Expand All @@ -205,7 +216,7 @@ class MySvgTranscoder private constructor(private var width: Float, private var

override fun getUserStyleSheetURI() = null

override fun getXMLParserClassName() = null
// override fun getXMLParserClassName() = null

override fun isXMLParserValidating() = false

Expand Down
51 changes: 27 additions & 24 deletions src/main/java/org/plantuml/idea/rendering/CompatibilityCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@
import static org.plantuml.idea.util.UIUtils.notification;

public class CompatibilityCheck {
public static boolean checkTransformer(PlantUmlSettings plantUmlSettings) {
if (!plantUmlSettings.isDisplaySvg()) {
return false;
}
if (plantUmlSettings.isRemoteRendering()) {
return false;
}

TransformerFactory factory = TransformerFactory.newInstance();
ClassLoader classLoader = factory.getClass().getClassLoader();

if (classLoader instanceof PluginAwareClassLoader) {
String clName = ((PluginAwareClassLoader) classLoader).getPluginDescriptor().getName();


plantUmlSettings.setDisplaySvg(false);

SwingUtilities.invokeLater(() -> {
Notifications.Bus.notify(notification().createNotification("Conflict detected with '" + clName + "'. Switching to PNG rendering.", NotificationType.WARNING));
});
return false;
}
return true;
}
public static boolean checkTransformer(PlantUmlSettings plantUmlSettings) {
if (!plantUmlSettings.isDisplaySvg()) {
return false;
}
if (plantUmlSettings.isRemoteRendering()) {
return false;
}
// if (true) {
// return true;
// }

TransformerFactory factory = TransformerFactory.newInstance();
ClassLoader classLoader = factory.getClass().getClassLoader();

if (classLoader instanceof PluginAwareClassLoader) {
String clName = ((PluginAwareClassLoader) classLoader).getPluginDescriptor().getName();


plantUmlSettings.setDisplaySvg(false);

SwingUtilities.invokeLater(() -> {
Notifications.Bus.notify(notification().createNotification("Conflict detected with '" + clName + "'. Switching to PNG rendering.", NotificationType.WARNING));
});
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
package org.plantuml.idea.preview.image.svg.batik;

import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.ImageLoader;
import org.apache.batik.transcoder.TranscoderException;
import io.sf.carte.echosvg.transcoder.TranscoderException;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.w3c.dom.Document;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class MySvgTranscoderTest {
@Test
public void sanitize() throws IOException, TranscoderException {
public void test() throws IOException, TranscoderException {
renderSvg("src/test/resources/testData/test2.svg");
renderSvg("src/test/resources/testData/test3.svg");

}

private static void renderSvg(String pathname) throws IOException, TranscoderException {
String text = FileUtils.readFileToString(new File(pathname), CharsetToolkit.UTF8);
ByteArrayInputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
Document svgDocument = MySvgDocumentFactoryKt.createSvgDocument(null, reader);
Document svgDocument = MySvgDocumentFactoryKt.createSvgDocument(null, FileUtils.readFileToByteArray(new File(pathname)));
//it shows what is in png document - unZOOMED values, not limited by px limit
ImageLoader.Dimension2DDouble outSize = new ImageLoader.Dimension2DDouble(0.0D, 0.0D);
BufferedImage image = MySvgTranscoder.createImage((float) 1.1, svgDocument, outSize);
Expand Down

0 comments on commit 825e10a

Please sign in to comment.