Friday, January 26, 2007

Generating SVG's with Qt

I've been working on a lot of things at once over the last week but I just remembered that I never mentioned something that I should have. In the beginning of the Qt 4.3 development phase I added a class called QSvgGenerator to QtSvg. QSvgGenerator is a paint device, meaning you can open QPainter on it and yes, that's right, you'll get an SVG XML stream back that you can save to a file or manipulate.

So now you can redirect your widget/window and have a snapshot of your application dumped to SVG format... Come on that's pretty cool. The generator still needs a lot of work, especially when it comes to complex text. But here's a weird, example. I made Qt render a simple animating bezier curve, then loaded html with Qt documentation and rendered that with opacity of .75 (which is why it looks very blend) and finally redirected to a painter opened on a QSvgGenerator. As a result I get a SVG (viewed, of course with, svgviewer) looking like this:

And the full output is here. So yeah, the concept of being able to load simple html and then save it as SVG is pretty neat.

Also boolean ops on paths are now in Qt. You'll find them in QPainterPath's. Since I already had the code and Andreas asked me for it, I added QPainterPath::intersects(const QPainterPath &other) and QPainterPath::contains(const QPainterPath &other) that can be used to check whether two paths intersect or whether one path fully contains the other. I still want to do some heavy optimisations on it, but I'd like to implement "Snap Rounding of Bezier Curves" instead of trying to find the right shortcuts to use reduced-predicates for the intersection finding algorithm.

14 comments:

stelt said...

http://chaos.troll.no/%7Ezrusin/sampleout.svg shows just plain text, cause it's not served as image/svg+xml
See http://wiki.svg.org/MIME_Type how to fix it.

Your article is very nice.

Zack said...

I know how, but I don't do administration on that server hence i won't. Thanks anyway.

ChrisHowells said...

Very fucking cool. Cookies for Zack.

Jason said...

He never stops.

Jason said...

He never stops.

Anonymous said...

What's the use case for this, when is this useful?

Anonymous said...

To anonymous:

I could think of an application that creates graphs and diagrams. You now have a simple method to export those graphs for use in external graphics applications, in a scalable (as in size) way.

The nice thing: You do not have to write any additional code to create those graphs. The same stuff that ends up on your display can end up everywhere.

Jeff Schiller said...

Another possible use: SVG as a screen mockup format. See http://blog.codedread.com/archives/2007/01/26/svg-as-a-screen-mockup-format/

Anonymous said...

"What's the use case for this, when is this useful?"

A lot of mobile phones have embedded svg viewers. Perhaps an easy way to display data on a phone?

Illissius said...

Damn Zack. Are you ten times as productive as everyone else, or do you just blog about it more?

Was the HTML rendering with WebKit Qt?

Marcos Issler said...

Hello Zack, do u have a mail for contact? I'm a brazilian programmer and work with maya and 3d animation developing tools with mel, c++, python, etc...
I have interest in QT to do interfaces and I see that u are a expert.
make contact. issler@ocafilmes.com
and see our demoreel at http://www.ocafilmes.com/reel.htm
Thanks. Marcos Issler.

Mike Eberhart said...

I have been just playing around with Qt for a while now to see what its capabilities are, and I was looking into the SVG stuff for an idea I wanted to try -- now I read what is coming in 4.3, and I am very excited. I think this functionality has tons of potential, and I am looking forward to it.

galileon said...

Hi, have you posted the code for using the SvgGenerator somewhere, or could you post it please? I am just starting to use QT, and had been using wxWidget for some time, but I can't seem to produce the svg file - it's producing a 0-byte file...

Cheers,

galileon.

puechl said...

Hello Zack,
Google has oriented me to your Blog for q=Qt+svg.I am sorry to ask a trivial question :

I have a routine that paints (scientific graph) onto a QPainter*.
I would like to use it to record an SVG file.
The doc in Qt Assistant on QSvgGenerator is not enough for my understanding.

I have done something that looks like this :
QPainter*mypainter=mySvgRender.painter();

(
since paintEngine() is protected I derived a MQSvgRender class that returns paintEngine()->painter()
)
I get no output file, or a crash.
Thanks for a code snippnet.