Python svg interaction with cairo, opengl and rsvg

I present a huge SVG file with a lot of elements with Cairo, OpenGL and rsvg. I draw svg on the surface of Cairo via rsvg and create an OpenGL texture to paint it. All perfectly. And now I need to interact with elements from SVG. For example, I want to guess an element by coordinates. And I want to change the background of some path in SVG. In the case of a background change, I think I can change the SVG DOM and somehow remake part of the SVG. But in the case of hit testing elements, I am completely confused.

So, is there any python library to interact with SVG? Can I stay with Cairo and rsvg and how can I implement it myself? Or is there a better way to visualize SVG in OpenGL and interact with it in python? All I want is to load the SVG, manipulate its DOM and make it

+3
source share
4 answers

I don't know much about librsvg, but it does not seem to have been updated since 2005, so I would be inclined to recommend using a different implementation.

If you have no dependencies on any Python libraries outside the standard library, you can use Jython with Batik. This allows you to add event handlers, as well as modify the DOM after rendering.

, Java, . .

Jython 2.2.1 (, ):

from java.awt.event import WindowAdapter;
from java.awt.event import WindowEvent;

from javax.swing import JFrame;

from org.apache.batik.swing import JSVGCanvas;
from org.apache.batik.swing.svg import SVGLoadEventDispatcherAdapter;
from org.apache.batik.swing.svg import SVGLoadEventDispatcherEvent;
from org.apache.batik.script import Window;

from org.w3c.dom import Document;
from org.w3c.dom import Element;
from org.w3c.dom.events import Event;
from org.w3c.dom.events import EventListener;
from org.w3c.dom.events import EventTarget;

class SVGApplication :

    def __init__(self) :

        class MySVGLoadEventDispatcherAdapter(SVGLoadEventDispatcherAdapter):
            def svgLoadEventDispatcherListener(e):
                # At this time the document is available...
                self.document = self.canvas.getSVGDocument();
                # ...and the window object too.
                self.window = self.canvas.getUpdateManager().getScriptingEnvironment().createWindow();
                # Registers the listeners on the document
                # just before the SVGLoad event is
                # dispatched.
                registerListeners();
                # It is time to pack the frame.
                self.frame.pack();

        def windowAdapter(e): 
            # The canvas is ready to load the base document
            # now, from the AWT thread.
            self.canvas.setURI("doc.svg");

        self.frame = JFrame(windowOpened = windowAdapter, size=(800, 600));

        self.canvas = JSVGCanvas();
        # Forces the canvas to always be dynamic even if the current
        # document does not contain scripting or animation.
        self.canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
        self.canvas.addSVGLoadEventDispatcherListener(MySVGLoadEventDispatcherAdapter()) ;

        self.frame.getContentPane().add(self.canvas);

        self.frame.show()

    def registerListeners(self) :
        # Gets an element from the loaded document.
        elt = self.document.getElementById("elt-id");
        t = elt;

        def eventHandler(e):
            print e, type(e)

            self.window.setTimeout(500,run = lambda : self.window.alert("Delayed Action invoked!"));
            #window.setInterval(Animation(), 50);

        # Adds a 'onload' listener
        t.addEventListener("SVGLoad", false, handleEvent = eventHandler );

        # Adds a 'onclick' listener
        t.addEventListener("click", false, handleEvent = eventHandler );



if __name__ == "__main__":
    SVGApplication();

:

jython -Dpython.path=/usr/share/java/batik-all.jar:/home/jacob/apps/batik-1.7/lib/xml-apis-ext.jar test.py
+2

blender. svg python. , dom .

+1

GObject librsvg Python 3; . .

0

( , ), rsvg, , . .

0

Source: https://habr.com/ru/post/1760046/


All Articles