xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thomas.dewe...@kodak.com
Subject Re: Extracting/Zooming to a single element
Date Thu, 24 Sep 2009 12:27:58 GMT
Hi Timo,

Timo Loist <Timo.Loist@uni-dortmund.de> wrote on 09/24/2009 08:12:21 AM:

> 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 ).

    You might try the SVG 'use' element:

        <use xlink:href="cards.svg#king_spades" x="100" y="100"/>

    Assuming the SVG card compilation is named 'cards.svg' in the
same directory as the SVG file containing the above use element.

    You might also be interested in looking at 
samples/solitaire/klondike.svg
Which uses this technique to implement klondike (and another less well
known solitaire card game).

> 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: batik-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
> 


Mime
View raw message