Hi,
I'm trying to isolate a single element (a card) from an SVG File.
To be concrete, I'm trying to display the "King of Spades" card from a
SVG card compilation done by David Bellot (
http://david.bellot.free.fr/svg-cards ).
What I want to do is to create a Swing Component, which displays me a
single card from this file. In order to do this, I have to isolate the
cards and assign a card to a component. To isolate a card, there are a
few possibilities:
- Extract the nodes from the SVG File
- Zoom the file, so you could just see the single card
I've made up my mind to use the zoom approach, because I don't want to
change the file itself and because there are a lot of common elements
(<defs>) in the file, which would be duplicated all over, if I would
isolate the cards into different SVG Files or break the DOM Tree into
several subtrees.
In a later step, I'm going to save the needed transformations in a file
(or their position) so I don't have to build the DOM-Tree at all, but
for the moment I want it to be dynamical.
Having looked through the mailing list, I crossed the "SVGLocatable"
Interface and a thread, which refers to the "showSelectedGraphicsNode"
from the org.apache.batik.apps.svgbrowser.FindDialog and I've done the
following by now, which draws heavily from the above mentioned method:
// Some Imports and the Class wrapping the method is missing here to
make it shorter
public static void main( String[] args )
{
JFrame f = new JFrame("Zoom to card" );
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500, 500);
JSVGCanvas cardDisplay = new JSVGCanvas();
UserAgent userAgent;
DocumentLoader loader;
BridgeContext ctx;
GVTBuilder builder;
GraphicsNode rootGN;
AffineTransform trans;
try {
// Create DOM
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory fact = new SAXSVGDocumentFactory(parser);
URI uri = new URI("./cards.svg");
SVGDocument svgDoc = (SVGDocument)
fact.createDocument(uri.toString());
// Boot SVG & CSS Dom like described in the Wiki
userAgent = new UserAgentAdapter();
loader = new DocumentLoader(userAgent);
ctx = new BridgeContext(userAgent, loader);
ctx.setDynamic(true);
builder = new GVTBuilder();
rootGN = builder.build(ctx, svgDoc);
// Locate group containing the card
SVGLocatable cardElement = (SVGLocatable)
svgDoc.getElementById("king_spade");
// Compute zoom to the card
SVGRect cardRect = cardElement.getBBox();
Dimension canvasSize = cardDisplay.getSize();
AffineTransform Tx = AffineTransform.getTranslateInstance(
cardRect.getX()-cardRect.getWidth()/2,
cardRect.getY()-cardRect.getHeight()/2);
// Do I need to scale?
double sx = canvasSize.width/cardRect.getWidth();
double sy = canvasSize.height/cardRect.getHeight();
double scale = Math.min(sx, sy) / 8;
if (scale > 1) {
Tx.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
}
Tx.preConcatenate(AffineTransform.getTranslateInstance
(canvasSize.width/2, canvasSize.height/2));
// change the rendering transform - maybe changing
"setPaintingTransform" instead?
cardDisplay.setRenderingTransform(Tx);
// Display the card
cardDisplay.setSVGDocument(svgDoc);
}
catch (IOException e) {
e.printStackTrace();
}
catch (URISyntaxException e) {
e.printStackTrace();
}
f.getContentPane().add(cardDisplay);
f.setVisible( true );
}
But it only displays the whole file, instead of zooming to the card.
What is worse: if I change the Transformation to a mock transformation
it doesn't affect the displayed cards at all. So I'm overlooking some
kind of auto-fitting feature, which I have to disable here?
Maybe another approach would be to use the "getTransformToElement"
Method on the SVGLocatable Interface to get the wished effect?
What am I doing wrong?
Thanks for any help in advance
Timo Loist
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]