Last active
August 29, 2015 14:02
-
-
Save ComFreek/9d651a8935c467143f2d to your computer and use it in GitHub Desktop.
Utility classes for transforming arbitrary SVG elements with Batik. Read more: http://comfreek.blogspot.com/2014/06/batik-how-to-transform-arbitrary-svg.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.comfreek.util; | |
import java.awt.geom.AffineTransform; | |
/** | |
* Utility class.<br> | |
* Its primary intent is to provide {@link #affineTransformToString(AffineTransform) affineTransformToString()}. | |
* | |
* @author ComFreek <comfreek@outlook.com> if not otherwise noted. | |
* @license MIT (for all parts whose author is ComFreek) | |
*/ | |
public class AffineTransformUtils { | |
private AffineTransformUtils() { | |
} | |
/** | |
* Converts an AffineTransform to a "matrix(...)" string representation as | |
* used in SVG files for the "transform" attribute. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/SVG11/coords.html#TransformAttribute">W3C SVG | |
* 1.1 Specification: The 'transform' attribute</a> | |
* @see <a | |
* href="https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform">Mozilla | |
* Developer Network: SVG transforma attribute</a> | |
* | |
* @author Jonathan Wood in a mail to the xmlgraphics-batik-users mailing list: <a href="http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-users/201208.mbox/%3cCAKiJDQTpJE-4hEGG-QMn=cDXK2tAn5H52TWBCZJxZ30pf15DYQ@mail.gmail.com%3e">click here</a> | |
* | |
* @param at The AffineTransform object | |
* @return Returns a "matrix(...)" string representation. for more | |
* information | |
*/ | |
public static String affineTransformToString(final AffineTransform at) { | |
double[] matrix = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; | |
at.getMatrix(matrix); | |
return matrixArrayToString(matrix); | |
} | |
/** | |
* Converts a double array in the form of {a, b, c, d, e, f} to a string | |
* representation in the form of "matrix(a b c d e f)". | |
* | |
* The returned string can be used in transform attributes of elements in | |
* SVG files. files. | |
* | |
* @see AffineTransformUtils#affineTransformToString(AffineTransform) | |
* @see <a | |
* href="http://www.w3.org/TR/SVG11/coords.html#TransformAttribute">W3C SVG | |
* 1.1 Specification: The 'transform' attribute</a> | |
* @see <a | |
* href="https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform">Mozilla | |
* Developer Network: SVG transforma attribute</a> | |
* | |
* @author Jonathan Wood in a mail to the xmlgraphics-batik-users mailing list: <a href="http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-users/201208.mbox/%3cCAKiJDQTpJE-4hEGG-QMn=cDXK2tAn5H52TWBCZJxZ30pf15DYQ@mail.gmail.com%3e">click here</a> | |
* | |
* @param vals A double array a | |
* @return Returns the string representation in the form of "matrix(a b c d e f)". | |
*/ | |
public static String matrixArrayToString(double[] vals) { | |
return new StringBuilder("matrix(").append(vals[0]).append(" ").append(vals[1]).append(" ").append(vals[2]).append(" ").append(vals[3]).append(" ").append(vals[4]).append(" ").append(vals[5]).append(") ").toString(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.comfreek.util; | |
import java.awt.geom.AffineTransform; | |
import org.apache.batik.parser.AWTTransformProducer; | |
import org.apache.batik.parser.TransformListParser; | |
import org.apache.batik.util.SVGConstants; | |
import org.w3c.dom.Element; | |
/** | |
* This class provides static utility methods for the use with Batik and SVG | |
* elements. | |
* | |
* @author ComFreek <comfreek@outlook.com> if not otherwise noted. | |
* @license MIT (for all parts whose author is ComFreek) | |
*/ | |
public class SVGUtils { | |
private SVGUtils() { | |
} | |
/** | |
* Applies an AffineTransform to a (SVG) element. | |
* <br> | |
* While this function works with all classes equal to or subclassing | |
* {@link org.w3c.dom.Element Element}, adding and modifying the "transform" | |
* attribute is probably of no effect. | |
* <br> | |
* Example: | |
* <pre> | |
* <code> // Document svgDoc = ...; | |
* Element elem = svgDoc.getElementById("your-id"); | |
* AffineTransform translateBy5Units = | |
* AffineTransform.getTranslateInstance(5, 0); | |
* transformElement(elem, translateBy5Units); | |
* | |
* AffineTransform scaleByFactor10 = | |
* AffineTransform.getScaleInstance(10, 10); | |
* transformElement(elem, scaleByFactor10); | |
* </code> | |
* </pre> | |
* | |
* @see #getElementTransform(Element) | |
* | |
* @param element The element. | |
* @param transform The AffineTransform you want to apply. The resulting | |
* transformation of the object is | |
* <code>transform.{@link AffineTransform#concatenate(AffineTransform) concatenated}(oldTransform)</code>, | |
* where <code>oldTransform</code> represents the current local (i.e. | |
* possible parents' transforms will not be taken into acconut) transform of | |
* the element. | |
*/ | |
public static void transformElement(final Element element, final AffineTransform transform) { | |
final AffineTransform oldTransform = getElementTransform(element); | |
transform.concatenate(oldTransform); | |
element.setAttributeNS(null, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, | |
AffineTransformUtils.affineTransformToString(transform)); | |
} | |
/** | |
* Retrieves and parses the transformation attribute of a Element into an | |
* AffineTransform object. | |
* <br> | |
* | |
* This function can cope with all transform values supported by | |
* {@link org.apache.batik.parser.TransformListParser TransformListParser}. | |
* These include <code>translate()</code>, <code>rotate()</code>, | |
* <code>scale()</code>, <code>skew()</code> and <code>matrix()</code>. It | |
* will also correctly handle empty or non-existing attributes (i.e. | |
* returning an Identity matrix). | |
* | |
* @see #transformElement(Element, AffineTransform) | |
* | |
* @author fireball in a mail to the xmlgraphics-batik-users mailing list: | |
* <a href="http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-users/201208.mbox/%3c1344872547972-4655199.post@n4.nabble.com%3e">click here</a> | |
* | |
* @param element The SVG element. | |
* @return An AffineTransform which equals the (local) transformations | |
* specified in the SVG element. | |
*/ | |
public static AffineTransform getElementTransform(final Element element) { | |
final String oldTransformStr = element.getAttributeNS(null, SVGConstants.SVG_TRANSFORM_ATTRIBUTE); | |
final TransformListParser tListParser = new TransformListParser(); | |
final AWTTransformProducer tProducer = new AWTTransformProducer(); | |
tListParser.setTransformListHandler(tProducer); | |
tListParser.parse(oldTransformStr); | |
return tProducer.getAffineTransform(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Consult Batik's documentation or Google if you don't | |
// know how to load a document. | |
// Document svgDoc = ...; | |
Element elem = svgDoc.getElementById("your-id"); | |
AffineTransform translateBy5Units = | |
AffineTransform.getTranslateInstance(5, 0); | |
transformElement(elem, translateBy5Units); | |
AffineTransform scaleByFactor10 = | |
AffineTransform.getScaleInstance(10, 10); | |
transformElement(elem, scaleByFactor10); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment