PDA

View Full Version : SVG: access coordinates of elements



bmpix
31st August 2012, 01:52
Hi all,

I want to load a file with vector graphics and do some simple modifications to each curve in it.
So I basically need to access some coordinates within each curve (i.e. control points for Bezier curves, or just even vertices of polylines). I thought of using SVG format, loading it with QtSvg. Now the question is, after I load SVG (apparently, with QGraphicsSvgItem?), how can I look into it, i.e. access separate elements and their coordinates?

Thanks!

ChrisW67
31st August 2012, 02:26
Use QtXML to open the SVG file as XML and manipulate it using the DOM or stream functions as appropriate.

bmpix
31st August 2012, 18:43
Thanks, that's great, but SVG contains lots of stuff besides XML, i.e. paths need additional parsing - Qt doesn't have anything for that?

d_stranz
31st August 2012, 19:04
When Qt reads an SVG file, it builds an internal representation of the SVG XML hierarchy into an "SVG document" containing "SVG nodes". When the SVG is rendered to the screen, this document hierarchy is traversed and turned into QPainter commands. As I answered in a similar post a week or two ago, you could adapt the code in the document and node classes to give you something you could interrogate and manipulate. It would be a whole lot of work (basically duplicating everything in the classes), but it could be done.

I would start first by looking at the internals of the QSvgRenderer class and see if you can extract the code that reads and parses the XML into the internal document. It would be nice if this could be turned into a hierarchy of QGraphicsItem instances rather than a hidden internal document structure. Then you could see and manipulate the individual child items however you want. You will probably have to invent a few new graphics item types along the way.

It is understandable why QtSvg is implemented in this way - the reader / renderer are independent of the Graphics / View system, so an SVG file can be read and rendered anywhere. The QGraphicsSvgItem is the simplest link between these two systems, where the graphics item simply provides the place for the renderer to paint the document contents. But if you want to be able to manipulate the SVG, you need a lot more visibility than the QtSVG architecture provides.

bmpix
31st August 2012, 20:11
Thank you guys for such detailed answers. Going through the implementation of QSvgRenderer and copying/altering the functionality seems a bit tedious to me, but maybe I will end up doing that if I don't find another library. It's weird though, the task I'm describing seems to me the most natural task to do with vector graphics, and yet I can't find any suitable solution...
If somebody knows a library that would help, I would really appreciate it.
Otherwise - thanks again for your help.

ChrisW67
1st September 2012, 00:29
Thanks, that's great, but SVG contains lots of stuff besides XML, i.e. paths need additional parsing - Qt doesn't have anything for that?

Yes, sure. You can manipulate the strings you extract from the XML using any of the string manipulation faciltiies in Qt. Paths etc. are deliberately easy to parse. There is even a LALR parser add-on for Qt 5 (that predates Qt 5) in you want to build some thing more elaborate. This is all good for manipulating SVG images but not really useful for real-time, on screen manipulation which I suspect is what you were really after.