Skip to content

Releases: css4j/echosvg

2.0

27 Feb 14:40
v2.0
Compare
Choose a tag to compare

All users are encouraged to upgrade, as the 1.x branch will now only receive security updates. Version 2.0 is new, but it passes far more tests than 1.2.4.

Highlights


Advanced CSS

Adds native support for several CSS improvements, which until now required the use of the Transcoding Helper but now are available out-of-the-box.

fill: var(--my-color, blue);
@property --my-length {
  syntax: "<length>";
  inherits: true;
  initial-value: 4px;
}
@supports (color: oklch(67% 0.18 270)) {
  g {
    --my-color: oklch(45% 0.3 264);
    --my-stroke-width: calc(1px + var(--my-length));
  }
}
@media screen and (300px < width <= 1000px) and (prefers-color-scheme: light) {
  text.myclass {
    font-size: calc(var(--my-FontSize) + 2pt);
  }
}

See also KEY_MEDIA.

  • The turn, Q, vw, vh, vmin, vmax, lh, rlh, rem and rex units.

  • calc() expressions, both in CSS properties/attributes and non-CSS attributes. You can write y = "calc(30% + 2vmin)" for example, like you'd do with modern web browsers.

  • The advanced attr() value that was recently implemented by Chromium-based web browsers.

ellipse {
  fill: attr(data-color type(<color>), #22a);
}
  • The initial, unset and revert CSS-wide keywords (this being SVG, revert is currently handled as unset).

Standards-compliant Resolution

In addition, it implements a true resolution concept: the resolution is no longer used in CSS unit conversions, matching the standards-compliant behaviour of web browsers. That resolution is also available to CSS Media Queries.

To make it available to the transcoder, the KEY_RESOLUTION_DPI transcoding hint was added. The old KEY_PIXEL_UNIT_TO_MILLIMETER transcoding hint can still be used, but is no longer used in CSS unit conversions (only in the encoding phase).


The transcoder module was split in 4 sub-modules: api, svg, svg2svg and tosvg

Sometimes an SVG library is embedded into an executable, and a common concern for both EchoSVG and Batik users in those cases is to make the size of the embedded modules as small as possible.

Notably, in the case of the Transcoder a number of unneeded classes may be included. For an example of such concern see

eclipse-platform/eclipse.platform.swt#1438 (comment)

The current transcoder module was designed as a monolithic do-it-all package, with users always carrying code that they do not intend to run. For example, the code to convert WMF to SVG was always there even if you just wanted to convert SVG to PNG.

So it was split in several submodules, in a way that backwards compatibility is kept (the old transcoder module still exists and provides all the classes), so users willing to minimize their dependencies can choose a smaller specific sub-module.

Version 2.0 splits the transcoder in 4 modules:

  • transcoder-api (API)
  • transcoder-svg (SVG to image)
  • transcoder-svg2svg (SVG to SVG)
  • transcoder-tosvg (conversions to SVG, currently only WMF to SVG)

In the typical case of rendering SVG as a PNG, the full 2.0 transcoder with dependencies fills a jar of 6.34 MB, while the specific SVG-to-image transcoder becomes a bit smaller (6.04 MB).

The gains are higher for the WMF to SVG case (3.38 MB) or the SVG-to-SVG (2.64 MB).


More flexible DOM (and transcoding from SVG)

Until now, before transcoding a file one has to specify whether it is SVG or HTML via the KEY_DOCUMENT_ELEMENT and KEY_DOCUMENT_ELEMENT_NAMESPACE_URI hints. Now the DOM factories use a different procedure, and in consequence those transcoding hints are ignored. For example if you are using the SVG-to-PNG transcoder, it will always look for SVG in any provided document.

However, if the file being processed is HTML instead of XHTML you still have to specify an HTML parser as explained in the wiki.


Transcoding with color profiles

If you transcode an SVG image which uses colors outside of the sRGB color palette (e.g. color(display-p3 1 1 0)), EchoSVG determines the smallest color gamut that fits your image and subsequently uses it. The color profile is automatically embedded in the resulting image, if needed.

Most of the color conversions are done via the AWT toolkit and, when converting a color to a smaller gamut (where that color isn't represented), it doesn't attempt any gamut mapping. Moreover there are several elements in the SVG specification where the sRGB color space is assumed (e.g. the filter primitives), and if one combines one of those with an out-of-gamut color, the results are less than perfect.

The CSSTranscodingHelper restricts the used colors to the Display P3 and A98 RGB gamuts, doing an accurate gamut mapping. If your SVG image includes colors outside of those gamuts, you may obtain better results using that tool.

Disclaimer

I only have access to devices with sRGB displays, so haven't visually checked the color-profiled PNG/JPG images. In that sense, the color profile support should be considered as untested. But the profiles are indeed in the images, and the pixel values seem correct.


Upgrading

If your build uses Gradle, do not forget to allow the download of the new dependencies from the Maven repository, with an includeGroupByRegex or similar:

repositories {
    maven {
        url = "https://css4j.github.io/maven/"
        mavenContent {
            releasesOnly()
        }
        content {
            includeGroupByRegex 'io\\.sf\\..*'

            // Alternative to the regex:
            //includeGroup 'io.sf.carte'
            //includeGroup 'io.sf.jclf'
            //includeGroup 'io.sf.graphics'
            //includeGroup 'io.sf.w3'
        }
    }
}

If you find any issue upgrading, please check MIGRATING_FROM_BATIK. Open an issue or discussion if necessary.

2.0 preview 1

25 Jan 15:42
v2.0-pre1
Compare
Choose a tag to compare
2.0 preview 1 Pre-release
Pre-release

This first preview of 2.0 is mainly intended to check how the transcoder module split is received, as it is a potentially controversial change. It could always be reverted or done differently.

Summary of the new features in 2.0:


Support for advanced CSS

Adds native supports for several CSS improvements, which until now required the use of the Transcoder Helper but now are available out-of-the-box.


In addition to this, it implements a true resolution concept: the resolution is no longer used in CSS unit conversions, matching the standards-compliant behaviour of web browsers. That resolution is also available to CSS Media Queries.

To make it available to the transcoder, the KEY_RESOLUTION_DPI transcoding hint was added. The old KEY_PIXEL_UNIT_TO_MILLIMETER transcoding hint can still be used, but is no longer used in CSS unit conversions (only in the encoding phase).


Split the transcoder module in 4 sub-modules: api, svg, svg2svg and tosvg

Sometimes an SVG library is embedded into an executable, and a common concern for both EchoSVG and Batik users in those cases is to make the size of the embedded modules as small as possible.

Notably, in the case of the Transcoder a number of unneeded classes may be included. For an example of such concern see

eclipse-platform/eclipse.platform.swt#1438 (comment)

The current transcoder module was designed as a monolithic do-it-all package, with users always carrying code that they do not intend to run. For example, the code to convert WMF to SVG was always there even if you just wanted to convert SVG to PNG.

So it was split in several submodules, in a way that backwards compatibility is kept (the old transcoder module still exists and provides all the classes), so users willing to minimize their dependencies can choose a smaller specific sub-module.

Version 2.0-pre1 splits the transcoder in 4 modules:

  • transcoder-api (API)
  • transcoder-svg (SVG to image)
  • transcoder-svg2svg (SVG to SVG)
  • transcoder-tosvg (conversions to SVG, currently only WMF to SVG)

In the typical case of rendering SVG as a PNG, the 2.0-pre1 transcoder with dependencies fills a jar of 6.33 MB, while the specific SVG-to-image transcoder becomes a bit smaller (6.03 MB).

The gains are higher for the WMF to SVG case (3.37 MB) or the SVG-to-SVG (2.59 MB).


More flexible DOM (and transcoding from SVG)

Until now, before transcoding a file one has to specify whether it is SVG or HTML via the KEY_DOCUMENT_ELEMENT and KEY_DOCUMENT_ELEMENT_NAMESPACE_URI hints. Now the DOM factories use a different procedure, and in consequence those transcoding hints are ignored. For example if you are using the SVG-to-PNG transcoder, it will always look for SVG in any provided document.

However, if the file being processed is HTML instead of XHTML you still have to specify an HTML parser as explained in the wiki.


Transcoding with color profiles (warning: experimental)

If you transcode an SVG image which uses colors outside of the sRGB color palette (e.g. color(display-p3 1 1 0)), EchoSVG determines the smallest color gamut that fits your image and subsequently uses it.

Unfortunately the color conversions are done via the AWT toolkit and aren't very precise. Moreover there are several places in the codebase where the sRGB color space is assumed, and the results are less than perfect.

If the SVG that you want to transcode uses color spaces outside of the sRGB gamut, you may want to consider using the CSSTranscodingHelper instead, as it uses the css4j color conversions which are more accurate (similar results to ColorJS).

1.2.4

25 Jan 13:41
v1.2.4
Compare
Choose a tag to compare

A first preview release of 2.0 is imminent, so it is time for a new stable version.

The fixes are much less important than in previous stable versions, but still good to have. The upgrade to css4j 5.1 means that the transcoder helper now has an advanced attr() support which is expected to be compatible with the forthcoming version 133 of Google Chrome.


Detail of changes

  • awt: avoid division by zero in feTurbulence processing [BATIK-1102].
  • dom: allow creating documents with null qualified name in GenericDOMImplementation.
  • parser: small performance improvement in NumberParser.equalsAny.
  • util: NormalizingReader was silently dropping one character on each call to read(cbuf[]).
  • util: make ParsedURL and ParsedURLData serializable.
  • util: use a fixed locale in case conversion when retrieving the decoder factory.
  • Gradle: do not depend on compile-only artifacts in the fat jars.
  • Make tests compatible with Java 23.
  • Tests: test arabic characters.
  • Upgrade to css4j 5.1.
  • Upgrade to css4j-awt 5.0.
  • Upgrade to jclf-text 5.0.2.
  • Upgrade to commons-io 2.18.0.
  • Upgrade to JUnit 5.11.4.
  • Upgrade to GrGit 5.3.0.
  • Upgrade to checkstyle 10.21.1.
  • Upgrade to dependency-check-gradle 12.0.1.
  • Upgrade to gradle-license-report 2.9.
  • Upgrade Gradle wrapper to 8.12.1.
  • README: use the assignment operator in the Gradle example.
  • Bump year to 2025 in NOTICE.

1.2.3

27 Sep 16:13
v1.2.3
Compare
Choose a tag to compare

New batch of backports from the master branch, with SVG 2.0 compliance fixes and color improvements.

Also fixes a rendering crash when relative URLs read from a jar: file are shorter than 4 characters (for example <use href="#a1">).


Detail of changes

  • bridge: update <use> and <image> nodes on changes to namespaceless href attribute.
  • bridge: detect circularities and non-SVG elements referred by <use>.
  • css: increase the accuracy of color conversions.
  • util: do not crash on jar: relative URLs of less than 4 characters, avoid string creation.
  • Tests: create images with the correct resolution in AbstractImageTranscoderTest.
  • Upgrade to css4j 4.4 (which adds support for the srgb-linear color space).
  • Upgrade Gradle wrapper to 8.10.2.

1.2.2

22 Aug 12:39
v1.2.2
Compare
Choose a tag to compare

As there is still a long way towards the 2.0 version, several SVG compliance fixes were backported from the master branch and are made available here, including an important performance improvement.

Detail of changes

  • anim,bridge: improve lenient parsing, especially that of paths, polygons and polyline points. Paths and point sets are now only parsed once, even if referenced by multiple <use> elements, which fixes an important performance bottleneck.
  • anim: allow unrecognized SVG elements in createElementNS() of SVG 1.1 implementation, aligning it with the 1.2 one.
  • bridge: give EMPTY_SHAPE a smaller footprint.
  • svggen: be a bit more efficient in allocating the rgb() serialization color buffer.
  • i18n: if the resource cannot be loaded, print a warning and return the key.
  • Tests: check embedded profiles in ImageComparator.
  • Upgrade Gradle wrapper to 8.10.
  • Upgrade to JUnit 5.11.0.
  • Update RELEASE_HOWTO.md with current practice.

1.2.1

15 Aug 09:00
v1.2.1
Compare
Choose a tag to compare

SVG2 compliance fixes

This release brings the latest fixes right before merging the Typed OM patch (the basis for the forthcoming 2.0). Basically contains SVG2 compliance fixes.

This is intended to be the last 1.x release, although maintenance 1.2.x releases may be published if security vulnerabilities are found in the near future.


Detail of changes

  • SVG2 compliance for the viewBox attribute, including calc() support.
  • anim: make SVGOMAnimatedRect.getUnderlyingValue() less prone to races.
  • anim,bridge: continue rendering if x/y/width/height attributes of line,image,svg,use are wrong [SVG2].
  • bridge: fix the handling of colors with percentage values in alpha channel.
  • bridge: fix a resource leak in BaseScriptingEnvironment.
  • codec: improve handling of gray images in PNGEncodeParam.getDefaultEncodeParam().
  • codec: clean up the usage of PNGEncodeParam, PNGDecodeParam and PNGImageWriterParams.
  • transcoder: compute image sizes in CSS context where appropriate [SVG2].
  • Gradle: make xml-apis a compile-only dependency.
  • Upgrade to css4j 4.3.1.
  • Upgrade to wrapper-validation action v4.

1.2

31 Jul 18:04
v1.2
Compare
Choose a tag to compare
1.2

Warning: dependency on xmlgraphics-commons was removed

If you use a Gradle build, be sure to add the following to the repositories configuration for css4j's Maven repository:

includeGroup 'io.sf.graphics'

The configuration for the repository should look like this:

maven {
    url "https://css4j.github.io/maven/"
    mavenContent {
        releasesOnly()
    }
    content {
        includeGroup 'io.sf.graphics'
        includeGroup 'io.sf.carte'
        includeGroup 'io.sf.jclf'
    }
}

Detail of changes

  • anim: share the user agent css loading code between 1.1 and 1.2 implementations.
  • anim,parser: support calc() values in animated rectangles.
  • Remove xmlgraphics-commons.
  • Tests: add more Mermaid tests.
  • Small javadoc tweaks.
  • Upgrade to css4j 4.3.

1.1.1

24 Jul 17:30
v1.1.1
Compare
Choose a tag to compare

Fix Java 8 compatibility of 1.1

A few Java 8 incompatibilities slipped into the codec module in 1.1, and were detected by the secondary CI that checks the artifacts uploaded to the Maven repository. These are fixed in 1.1.1.

Note, however, that on Java 8 the new features introduced in the ImageIO writer will not work, due to lack of support by Java 8.

If you use the default PNGTranscoder you should be fine, but if you are a SVGGraphics2D user you may want to upgrade to Java 11 or later.

1.1

24 Jul 08:19
v1.1
Compare
Choose a tag to compare
1.1

Highlights

Security fixes

Two security vulnerabilities in the util module were fixed:

  • #98 [CWE-22]
  • Set connect and read timeouts in ParsedURLData [BATIK-1366] [CWE-770]

Adapt to new module name of xmlgraphics-commons

The next version of the xmlgraphics-commons dependency will use the org.apache.xmlgraphics.commons module name, different to the one that was being used in EchoSVG until now (based on the Maven filename-based module name).

If you experience any difficulty due to the change, please use a plugin like Moditect for Maven or extra-java-module-info for Gradle. Or you could wait until the next version of xmlgraphics-commons is released and then set an explicit dependency.


More SVG2 compatibility

  • More resilience against missing or wrong href, width, height, rx, ry, x and y attributes.
  • Full support for the namespaceless href attribute even in animations.

PNG codecs now support ICC color profiles

The native PNG codec and the ImageIO ImageWriter now support color profiles automatically.


Color profiles in SVG Generator, in colors and embedded PNG images

See https://github.com/css4j/echosvg/wiki/SVG-Generator


Configurable compression level for embedded PNG images in the SVG Generator

See SVGGeneratorContext.setCompressionLevel().


New rendering hints in the PNG transcoder

Rendering hints KEY_KEYWORD_TEXT, KEY_INTERNATIONAL_TEXT and KEY_COMPRESSED_TEXT allow embedding textual information (like copyright, author, description, etc) in rendered PNG images. And KEY_COMPRESSION_LEVEL sets the compression level used in the PNG encoding (the default native encoder uses 9 by default, which is excessive for some use cases).

All of these hints work with both the native and the ImageIO adapters.


Per-module Fat-jars

If you manage your classpath manually and only require a specific module, get a fat-jar specific for your use case.

See https://github.com/css4j/echosvg/wiki/Uber-Jar


Detail of changes

  • util: fix arbitrary file access during archive extraction. [security, CWE-22]
  • util: set connect and read timeouts in ParsedURLData [BATIK-1366]. [security, CWE-770]
  • Modules: switch to org.apache.xmlgraphics.commons as xmlgraphics-commons module name.
  • Remove a few redundant interface usages, other cleanups.
  • anim: support animatable namespaceless href attribute from SVG2.
  • anim: allow missing width and height attributes in <rect> [SVG2].
  • anim, bridge: the version attribute isn't part of SVG anymore, just check for 1.2.
  • bridge: be tolerant to missing or malformed href attribute in image elements [SVG2].
  • bridge: tolerate wrong width, height, rx and ry attributes in <rect> [SVG2].
  • bridge: tolerate wrong or missing rx and ry attributes in <ellipse>, r in <circle> [SVG2].
  • bridge: more resilience against missing or incorrect shape attributes [SVG2].
  • bridge: nullcheck the animation engine in SVGAnimationEngine.
  • codec: support ICC color profiles in native PNG codec.
  • codec: fix NPE writing the zTXt chunk.
  • codec: support ICC color profiles in ImageIOPNGImageWriter.
  • codec: configure the PNG compression level, support all the text chunks.
  • codec: add a null check in ImageIOJPEGImageWriter, other small improvements.
  • css: remove dependency on xmlgraphics-commons.
  • dom: check the namespaceless href attribute first.
  • extension: simplify ColorSwitchBridge.createPaint().
  • extension: resource was in a directory with wrong name.
  • script: give access to org.mozilla.javascript.EcmaError in the Rhino shutter [BATIK-912].
  • svggen: support colors in non-sRGB color spaces, via color() function.
  • svggen: support images based on ICC color profiles in drawImage().
  • svggen: make the compression level of the embedded PNG images configurable.
  • svggen: add Mac Glyph names for 210 & 257.
  • transcoder: add the KEY_COMPRESSION_LEVEL, KEY_KEYWORD_TEXT, KEY_INTERNATIONAL_TEXT and KEY_COMPRESSED_TEXT hints.
  • transcoder: do not close the output stream in PNGImageEncoder.
  • Unmerge codec packages from transcoder module, except for three classes.
  • dom: fix XPath regression introduced by commit 8164dd7 (BATIK-1329: Remove xalan). Bug reported by Pavel Braginskiy in July 17 to the batik-users mailing list.
  • JMH: move DoubleStringPerformanceMark to a svggen.jmh package for improved modular compatibility.
  • Source formatting (pre-requisite to enable code style tools).
  • Enable checks with the Checkstyle static analysis tool.
  • Tests: test images from canvg's test suite #92.
  • Tests: switch to a SVG 1.1 DTD in a number of test sample files.
  • Tests: refactor to be more IDE-friendly.
  • Tests: fix CodeQL alert 28.
  • Tests: a number of other improvements.
  • Distribution: add a Main-Class attribute to a few manifests.
  • Gradle: use implementation instead of api in several places.
  • Gradle: add the ability to create all-deps jar files for individual modules.
  • Upgrade to Mozilla Rhino 1.7.15.
  • Upgrade to xml-dtd 4.3.
  • Upgrade to JUnit 5.10.3.
  • Upgrade to extra-java-module-info 1.8.
  • Upgrade to grGit 5.2.2.
  • Upgrade Gradle wrapper to 8.9.
  • CI: do not exclude any test.
  • Run CI on Java 11 and 21.

1.0.1

20 Nov 15:06
v1.0.1
Compare
Choose a tag to compare

This is a bugfix release and all users are encouraged to upgrade.

Detail of changes

  • svg-dom: fix a bug copying transforms [BATIK-1361].
  • transcoder: improve the @supports logic in CSSTranscodingHelper.
  • Gradle: remove redundant module dependencies.
  • Gradle: use dependency-license-report to check dependency licensing.
  • Upgrade to css4j 4.2.2.
  • Upgrade to JMH 1.37.
  • Upgrade to JUnit 5.10.1.
  • Upgrade to GrGit 5.2.1.
  • Upgrade to extra-java-module-info version 1.6.
  • Upgrade to org.owasp.dependencycheck 8.4.2.