I am parsing svg files with only a polyline element in java using the batik libary. This is an example svg file:
<svg fill-rule="evenodd" height="0.38in" preserveAspectRatio="none"
stroke-linecap="round" viewBox="0 0 150 225" width="0.25in">
<style type="text/css">
.pen1 { stroke: rgb(0,0,0); stroke-width: 19; stroke-linejoin: round;}
</style>
<g>
<polyline class="pen1" fill="none" points="10.0,-95 132.0,2.5 10,105 "/>
</g>
<g/>
</svg>
After that I perform some manipulations on the dom element, specifically changing the viewBox to the bounding box of the parsed polyline points and changing width
and height
parameters to 500px.
Now I am looking for a way to extract the manipulated (scaled and translated) points of my polyline.
Any idea how this could be done?
EDIT 1
I tried the approach suggested by Robert Longson but apparently getTransformToElement
always returns the identity matrix, so the points remain the same. Maybe I got something wrong with my code?
if ((baseElement instanceof SVGLocatable) && (e instanceof SVGElement)) {
SVGSVGElement docSVGElement = (SVGSVGElement) baseElement;
SVGLocatable locatable = (SVGLocatable) baseElement;
SVGElement svgPolyline = (SVGElement) e;
SVGMatrix transformationMatrix = docSVGElement.createSVGMatrix();
transformationMatrix = locatable.getTransformToElement(svgPolyline);
for (Point2D p : points) {
SVGPoint svgPoint = docSVGElement.createSVGPoint();
svgPoint.setX((float) p.getX());
svgPoint.setY((float) p.getY());
SVGPoint svgPoint1 = svgPoint.matrixTransform(transformationMatrix);
normalizedPoints.add(new Point2D.Float(svgPoint1.getX(),svgPoint1.getY()));
}
}
e
is one of the PolyLine Elements in the dom structure.
It is working now. Use the approach in the first edit. Setting transformationMatrix = locatablePolyline.getCTM();
as transformation matrix does the trick. Then just apply the matrix to every point in the path. Thanks Robert for the hint!
Don't forget to initialize svg css dom interfaces, for example with the following code:
Document doc = factory.createSVGDocument(f.toURI().toString());
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
builder.build(ctx, doc);
Otherwise you cannot use the operations on SVGLocatables
.