Hello,

Earlier I received some very useful help about getting the computed style of elements. However, I've run into another problem I'm not sure how to solve. For some of the image processing I'm doing, I want to be able to load an SVG file, insert a stylesheet that modifies the elements in that file, read some of the resultant characteristics from the graphics node, then remove the stylesheet. However, when I insert a stylesheet at runtime, it seems not to affect the computed style and shape nodes of elements in the document. If I make similar changes to the presentation elements of individual elements, the effects are programmaticly available immediately, but if I insert a "style" element, nothing seems to change.

At first I thought this was similar to a problem in the FAQ about needing to use an update manager. However, running the code inside an update manager's thread didn't change anything. When I write the file with CSS inserted to disk and open it, the style is applied properly, but it seems like there should be a more efficient way than having to reload the entire SVG file. Does anyone have any advice? I've attached a test case that shows what I've been trying to do.

I'm running a recent SVG snapshot on JVM 1.5.0_07 on Microsoft Windows XP.

Thank you for your help,
Xavid
import static org.apache.batik.dom.svg.SVGDOMImplementation.SVG_NAMESPACE_URI;

import java.io.OutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.batik.Version;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGDefsElement;
import org.w3c.dom.svg.SVGRectElement;
import org.w3c.dom.svg.SVGSVGElement;
import org.w3c.dom.svg.SVGStyleElement;

public class BatikTestCase {

        public static void main(String[] args) {

        System.out.println(System.getProperty("java.version"));
        System.out.println(Version.getVersion());
        
        // Create a new SVG document
        DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
        final Document doc = impl.createDocument(SVG_NAMESPACE_URI, "svg", 
null);
        
        // Set up stuff for computed style
        UserAgentAdapter ua = new UserAgentAdapter();
        DocumentLoader loader = new DocumentLoader(ua);
        BridgeContext ctx = new BridgeContext(ua, loader);
        ctx.setDynamicState(BridgeContext.DYNAMIC);
        GVTBuilder builder = new GVTBuilder();
        GraphicsNode gvt = builder.build(ctx, doc);
        
        // Set up update manager?
        UpdateManager um = new UpdateManager(ctx, gvt, doc);
        um.resume();
        
        final SVGSVGElement svg = (SVGSVGElement)doc.getDocumentElement();
        
        // It has a CSS engine...
        System.out.println(ctx.getCSSEngineForElement(svg));
        
        // Add CSS style in the update manager thread
        // Calling changeStyle directly without using an update manager also
        // didn't work
        try {
            um.getUpdateRunnableQueue().invokeAndWait(new Runnable() {
                public void run() {
                    changeStyle(doc, svg);
                }
            });
        } catch (InterruptedException ie) {
            System.err.println(ie);
            System.exit(1);
        }
        
        // Create a rect
        SVGRectElement e = 
(SVGRectElement)doc.createElementNS(SVG_NAMESPACE_URI, "rect");
        svg.appendChild(e);

        e.setAttributeNS(null, "height", "11");
        e.setAttributeNS(null, "width", "11");
        // Author stylesheets override presentation attributes
        e.setAttributeNS(null, "fill", "red");
        
        // The rect also has (the same) CSS engine...
        System.out.println(ctx.getCSSEngineForElement(e));

        // This prints "rgb(255, 0, 0)", not "rgb(0, 0, 255)" like I want
        
System.out.println(svg.getComputedStyle(e,null).getPropertyValue("fill"));
        
        // Changing the presentation attribute directly works
        e.setAttributeNS(null, "fill", "green");
        
System.out.println(svg.getComputedStyle(e,null).getPropertyValue("fill"));
        
        // If you write the document and open it, the rectangle is blue
        writeDocument(System.out, doc);
        }
    
    public static final void changeStyle(Document doc, SVGSVGElement svg) {
        SVGDefsElement defs = 
(SVGDefsElement)doc.createElementNS(SVG_NAMESPACE_URI, "defs");
        SVGStyleElement style = (SVGStyleElement)doc
                                .createElementNS(SVG_NAMESPACE_URI, "style");
        style.setAttributeNS(null,"type","text/css");
        style.appendChild(doc.createCDATASection("rect {fill: blue;}"));
        defs.appendChild(style);
        svg.insertBefore(defs,svg.getFirstChild());
    }
    
    public static void writeDocument(OutputStream o, Document doc) {

        // Prepare the DOM document for writing
        Source source = new DOMSource(doc);

        // Prepare the output file
        Result result = new StreamResult(o);

        try {
            // Write the DOM document to the file
            Transformer xformer = 
TransformerFactory.newInstance().newTransformer();
            
            xformer.transform(source, result);
        } catch (TransformerException te) {
            System.err.println(te);
            System.exit(1);
        }
    }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to