Releases: css4j/echosvg
2.0 preview 1
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.
-
Custom properties (
var()
function). -
The
@property
rule (registered custom properties). -
Media Queries level 4, including the
prefers-color-scheme
media feature. As a result, theKEY_PREFERS_COLOR_SCHEME
transcoding hint was added. -
The
vw
,vh
,vmin
,vmax
,lh
,rlh
,rem
andrex
units. -
calc()
expressions, both in CSS properties/attributes and non-CSS attributes. -
The
initial
,unset
andrevert
CSS-wide keywords (this being SVG,revert
is currently handled asunset
). -
The advanced
attr()
value that Google Chrome 133 is shipping.
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
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 inGenericDOMImplementation
. - parser: small performance improvement in
NumberParser.equalsAny
. - util:
NormalizingReader
was silently dropping one character on each call toread(cbuf[])
. - util: make
ParsedURL
andParsedURLData
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
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 namespacelesshref
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
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
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, includingcalc()
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
andPNGImageWriterParams
. - 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
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
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
Highlights
Security fixes
Two security vulnerabilities in the util
module were fixed:
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
andy
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
andheight
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 inimage
elements [SVG2]. - bridge: tolerate wrong
width
,height
,rx
andry
attributes in<rect>
[SVG2]. - bridge: tolerate wrong or missing
rx
andry
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
andKEY_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 asvggen.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 ofapi
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
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 inCSSTranscodingHelper
. - 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.
1.0
This is the first major release since the fork from Batik, and a number of improvements have been introduced.
Here is the list of changes since the fork, starting with the improvements after the last milestone release (0.3.3). Several items that were just refinements over previous updates were removed from the list, or merged, in order to improve readability.
Detail of changes
since 0.3.3
- transcoder: support the
KEY_USER_STYLESHEET_URI
hint inCSSTranscodingHelper
. - transcoder: throw a
TranscoderException
in case of error inKEY_SVG_SELECTOR
, instead of a DOM exception. - transcoder: fix
KEY_ALTERNATE_STYLESHEET
support inCSSTranscodingHelper
. - transcoder: avoid useless null check.
- util: remove useless null checks.
- util: remove useless null checks.
- bridge: remove useless null check.
- bridge: fix NPE in
DefaultXBLManager
[BATIK-1313]. - bridge,css,swing: avoid unnecessary conversions to and from float/double.
- Improve code readability (code style).
- Fix several CodeQL alerts.
- Adjust the precision of operands in several floating-point operations.
- Add a comment to io.sf.carte.echosvg.awt's module-info.
- Upgrade to css4j 4.2 and xml-dtd 4.2.1.
- Upgrade to xmlgraphics-commons 2.9.
- Upgrade to extra-java-module-info 1.4.2.
- Enable dependabot for Github actions.
- Upgrade to
actions/checkout@v4
.
0.3.3
- dom: implement
matches()
,querySelector()
andquerySelectorAll()
. - transcoder: add the
KEY_SVG_SELECTOR
transcoding hint. - transcoder: use
SVGConstants.SVG_SVG_TAG
inCSSTranscodingHelper
. - transcoder: support namespaceless svg elements inside plain HTML (#83).
0.3.2
awt
: synchronize update of static field with class instead of instance.awt
: useBoolean.parseBoolean
instead ofvalueOf
inGraphicsUtil
.bridge
: add null checks inDefaultScriptSecurity
andSVGFontFamily
.dom
: do not callgetNodeName()
fromAbstractElementNS
constructor, as it uses a field not yet initialised by subclasses.dom
: use a lock instead of synchronized blocks inAbstractDocument
andDocumentDescriptor
.dom
: move a null check to the right place inAbstractDocument
.extension
: remove protected field fromPrefixableStylableExtensionElement
that was shadowing a superclass protected field.gwt
: make sure that counter increments and decrements are atomic inAWTGlyphGeometryCache
.script
: remove useless null check fromInterpreterPool
.swing
: remove useless null check fromJSVGComponent
.transcoder
: avoid NPE when transcoding non-SVG documents.- Replace
StringBuffer
withStringBuilder
. - Tests: use a different interned string than Batik, to synchronize.
- Tests: safer lazy static initialisation in
AbstractRenderingAccuracyTest
. - Javadoc improvement.
0.3.1
- awt: statically evaluate
isColorConvertOpAplhaSupported
. [BATIK-1354] - bridge: be tolerant to missing references. #80
- css: do not stop CSS processing when an unknown or wrong value is found. #78
- css: support Level 4 CSS Color (and Level 5
color-mix()
) values in sRGB gamut. #77 - css: fix NPE in
CSSEngine
when the document has nodocumentURI
. - dom: support the namespaceless
href
attribute of SVG2. - dom: support surrogate characters.
- gvt: fix race conditions in
AWTGlyphGeometryCache
(includes BATIK-1271). - gvt: fix SVG to PNG Rendering due to missing Arabic characters from the map. Based on patch by Paritosh Chauhan [BATIK-1355]
- transcoder: add methods to transcode from a
TranscoderInput
and aDocument
instance using the Helper. - transcoder: do not overwrite the error handler in the
CSSTranscodingHelper
. - Tests: make less verbose the rendering tests that expect errors.
0.3
- Improve the security model
- dom,anim: add
InputStream
+encoding method variant toDocumentFactory
. - transcoder,anim,dom: add encoding support to
TranscoderInput
. - anim: throw an
IllegalArgumentException
on root mismatch inSAXSVGDocumentFactory
. - bridge: avoid NPE when using non-PX units in an element.
- Use default implementations for the deprecated
getPixelToMM()
method (#59) - Use JDK's XPath support #76 (ported from: BATIK-1329: Remove xalan, Copyright of that change is ASF)
- Tests: fix a few
null
-empty string inconsistencies in OnLoad tests.
0.2.2
- bridge: default to antialiasing in
SVGClipPathElementBridge
. May fix #53 - transcoder: allow SVG embedded into XHTML in
XMLAbstractTranscoder
. #69 - transcoder: check for the correct SVGDOM implementation version in XML transcoding. #68
- transcoder: accurate computation of
stringWidth
inCSSTranscodingHelper
. - transcoder: adjust visibility of non-public types that were being referenced by
SVGTranscoder
public fields. - dom: deprecate
XMLReader
variant ofDocumentFactory.createDocument
, addsetXMLReader
. #71 - Small javadoc fixes.
0.2.1
- Deprecate
getPixelToMM()
andgetPixelToMillimeter()
for removal (#59). - Support the
transparent
color identifier. - awt: remove commented code from
ImageTagRegistry
. - bridge: initial fix to
SVGBrokenLinkProvider
. (#52) - css: accept
display: inline-block
as valid CSS. - css: do not stop processing when finding a custom property.
- css: ignore rules that are not supported instead of stopping processing.
- css: add a constructor with initial capacity in
StringMap
. - gvt: remove unreachable conditional blocks.
- svg-dom: fix relative move after path closure in
getNormalizedPathSegList
(#50) - transcoder: add a CSS rendering helper utility.
- transcoder: provide the old
PNGRegistryEntry
in module-info. - transcoder: correctly parse the
KEY_ALLOWED_SCRIPT_TYPES
hint (#56) - transcoder: reorder the
module-info
exports and requires. - util: add method
Platform.isOSX()
, deprecate public fieldisOSX
(#51) - Use try-with-resources in several places.
- Tests: explicitly set SVG version in samples that are not compatible with 1.2.
- Tests: use SVG 1.1 DTD instead of 1.0 in some 1.2 sample files.
- Tests: new
normalizedPathSegList
test. - Tests: anim: add a test for
getNormalizedPathSegList()
, see #50 - Tests: fix non-conformant
font-size
style declarations in test files. - Tests: split the ECMAScript tests for easier debugging.
- Add
RELEASE_HOWTO.md
with release steps.
0.2
- Migrate from Apache Xalan to EchoXSL. See #46
- bridge: rename
finalize()
toclose()
, implementCloseable
inBridgeContext
. See #38 - transcoder: remove
finalize()
method fromSeekableStream
. See #38 - bridge,script: remove public methods returning an
AccessControlContext
(final part of #36). - script: simplify the SecurityManager implementation of
EchoSVGSecurityController.getDynamicSecurityDomain()
(related to #36). - anim: round values to nearest integer during the interpolation.
- Tests: improve the rendering tests documentation.
0.1.2
- Refactor classes that use deprecated Security APIs, deprecate as needed. #36
- svg1.2: support attribute
text-align="center"
in SVG 1.2 flow elements. #33 - anim: avoid potential NPE.
- anim: remove protected fields that were shadowing superclass fields.
- awt: avoid an undesirable cast in
AbstractRable
. - awt: implement
SVGComposite.hashCode()
. - awt: fix rounding in a mathematical expression.
- awt: prevent three NPEs.
- awt: change class
DisplacementMapRed.TileOffsets
visibility to public. - awt: remove commented code.
- bridge: implement
DefaultXBLManager.DefinitionRecord.hashCode()
. - bridge: fix conditional in
GlyphLayout
. - gvt: fix implementation of
GVTAttributedCharacterIterator.getRunLimit(Set)
. - gvt: avoid potential NPE in
DynamicRenderer
. - svgrasterizer: prevent NPE.
- transcoder: return null on null input in
WMFTranscoder.getCompatibleInput()
. - util: use a volatile field in
HaltingThread
. - util: add a method to shut down
CleanerThread
, use a timeout when retrieving the queue. - util: prevent two NPEs in
ClassFileUtilities
. - Tests: deploy a new image comparison infrastructure.
- Tests: update test references with more accurate images.
- Tests: replace resources for scripting jar files.
- Tests: use free font in flowTextAlign test, accept Xfce variation on systemColors.
- Tests: fix scripting/domSVGColor test.
- Tests: fix samples/tests/spec12/text/flowText4.svg
- Tests: improved error message in
MemoryLeakTest
. - Tests: throw error that was being ignored in
JPainterCompare
. - Javadoc fixes.
0.1.1
- Generator: support decoration attributes in text elements #16
- Generator: conversions to SVG fonts now support
strikethrough-*
andunderline-*
attributes #17 - Script service provider metadata is at wrong module #20
- DOM:
Node.isEqualNode()
gives incorrect results #18 - Tests: the old Batik tests were overhauled and converted to JUnit (version 4 first, later version 5).
0.1
- New CSS engine supporting level 4 selectors and RGBA colors (with alpha channel).
codec
andtranscoder
packages were merged, runtime circular dependency removed. See #11.- Pyhton and Tcl scripting removed (they were already commented out in Batik), see #12 and #13.
- Removed support for PDF vector image format (which introduced a hidden FOP-Batik circular dependency, see #10).
- Remove the useless
shared-resources
package, those resources are now inserted into theMETA-INF
directory of the jar files. - Build system switched to Gradle (#8).
- BATIK-1296:
AbstractDocument.importNode(Node, boolean)
does not set the attributes of elements. - BATIK-1227: Image filters encoded with Base64 in the SVG throw "Content not allowed in prolog" exception. Fix by Dan Caprioara.
- BATIK-1285: Batik fails to parse an svg with missing 'offset' attribute. Based on fix by Konstantin Bulenkov.
- BATIK-1290: `AbstractGraphicsNode.pai...