ofxSVG !

Hello Of!

I’ve been using Theo’s ofxSVGLoader a lot and it’s great but I wanted something different, something more convenient that fit better to my workflow. So I decided to start writing a new little addon for handling SVG files.

It’s a work in progress and it’s really not finished but here’s a small list of the features I wrote so far:

  • Depth (2D z order).

  • One or Multiple Layers support.

  • All primitives of Illustrator are working!

  • Stroke and Fills support.

  • Stroke Weight support.

  • Support for single and multiline texts.

  • Rich Text and Fonts Support (with FTGL in option).

  • Most AI PathFinder operation are supported.

  • Illustrator SVGs and “Preserve Illustrator Editing Capabilities” SVGs are supported too!

(Opacity and matrix transforms(rotations) are not supported for the moment. Paths are not supported neither but will certainly be tonight!)

[attachment=0:3u6gdu4y]ofxSVG.zip[/attachment:3u6gdu4y]

The use of this addon is pretty straight forward:

  
  
// Setup and load SVG  
//--------------------------------------------------------  
ofxSVG svg;  
svg.setup("mySvg.svg");  
  
// Draw everything  
//--------------------------------------------------------  
svg.draw();   
  
// Draw by layers  
//--------------------------------------------------------  
for(int i=0; i<svg.layers.size(); i++)   
    svg.layers[i].draw();  
  
// Draw by Objects  
//--------------------------------------------------------  
for(int i=0; i<svg.layers[0].objects.size(); i++)   
    svg.layers[0].objects[i].draw();  
  

For now every SVGObjects only consists in an Opengl display list for the rendering so you can’t access the vertexs directly (I’ll try to manage that in the next versions).

Something really useful is that you can read back the names you gave to the layers and to the different objects. Which mean that you could for example built an entire GUI Layer inside your favorite Vector Graphic Editor and then read it back in OF! (ex: by tagging a rectangle with something like “slider:background” you get enough datas to build the slider with any GUI system)

  
  
// Print Layer Name  
//--------------------------------------------------------  
cout<<svg.layers[0].name<<endl;  
  
// Print Object Name and type  
//--------------------------------------------------------  
cout<<svg.layers[0].objects[0].name<<endl;  
cout<<svg.layers[0].objects[0].type<<endl;  
  

Unfortunately I had to hack ofxXMLSettings just a little to be able to parse the svg correctly (by the way I think this can be a good addition to the existing addon, actually it just enable to parse xml datas even if you don’t know the tags name and more important it allow to parse data in the right order, which is very useful/needed sometimes) :

in ofxXMLSettings.h:

  
  
int     getNumTags();  
string getName(int which = 0);  
string getValue(int which = 0);  
string	getAttribute(const string& attribute, int which = 0);  
bool    pushTag(int which = 0);  
  

and in ofxXMLSettings.cpp:

  
  
int ofxXmlSettings::getNumTags(){  
	TiXmlHandle tagHandle = storedHandle;  
	int count = 0;  
	TiXmlElement* child = storedHandle.FirstChildElement().ToElement();  
	for (count = 0; child; child = child->NextSiblingElement(), ++count){}  
	return count;  
}  
//--------------------------------------------------------  
string ofxXmlSettings::getName(int which){  
	TiXmlHandle tagHandle = storedHandle;  
  
    int i = 0;  
	TiXmlElement* child = storedHandle.FirstChildElement().ToElement();  
	for (; i<which && child; i++, child = child->NextSiblingElement()){}  
  
    return (i==which) ? child->ValueStr() : "";  
}  
//--------------------------------------------------------  
string ofxXmlSettings::getValue(int which){  
	TiXmlHandle tagHandle = storedHandle;  
  
    int i = 0;  
	TiXmlElement* child = storedHandle.FirstChildElement().ToElement();  
	for (; i<which && child; i++, child = child->NextSiblingElement()){}  
    const char* value;  
    if(i==which) value = child->GetText();  
    return (value!=NULL) ? value : "";  
}  
//--------------------------------------------------------  
string ofxXmlSettings::getAttribute(const string& attribute, int which){  
	TiXmlHandle tagHandle = storedHandle;  
    int i = 0;  
	TiXmlElement* child = storedHandle.FirstChildElement().ToElement();  
	for (; i<which && child; i++, child = child->NextSiblingElement()){}  
    const char* attributeValue;  
    if(i==which) attributeValue = child->Attribute(attribute.c_str());  
    return (attributeValue!=NULL) ? attributeValue : "";  
}  
//--------------------------------------------------------  
bool ofxXmlSettings::pushTag(int which){  
	TiXmlHandle isRealHandle = storedHandle.Child(which);  
  
	if( isRealHandle.ToNode() ){  
		storedHandle = isRealHandle;  
		level++;  
		return true;  
	}  
	return false;  
}  

And you will need this very small ofxFTGL addon to render the texts correctly (or disable FTGL by commenting this line in ofxSVG.h:

  
 #define USE_OFXFTGL   

(FTGL Texts rendering seems a bit better than the classic OF Texts rendering)
[attachment=2:3u6gdu4y]ofxFTGL.zip[/attachment:3u6gdu4y]

This is a work in progress, so I may be spamming this post again!
I really think that the SVG format can offer a lot more possibilities than just importing vectors (as I was saying with my GUI example) … and this is why I’m posting that here, and feel very exited :slight_smile:

Please feel free to post every comments or suggestions!

Thanks!

Simon.

ps: The birth of this addon would not have been that easy without the incredible works of OF developers and without this great forum!
pps: If you want to use text you will still need to add the fonts you are using inside “data/fonts” (and sometimes rename them as they are in the svg).
ppps: ofxSVG_2_ofxGUI is on the way!
ppps: If you are using Illustrator don’t forget to use “Preserve Illustrator Editing Capabilities” when you save you’re SVG or you will have troubles next time you open it!

Edit* You’ll need this too for the rendering:
[attachment=1:3u6gdu4y]ofxDisplayList.zip[/attachment:3u6gdu4y]

ofxFTGL.zip

ofxSVG.zip

ofxDisplayList.zip

Hey wow - this looks great!

Looks like it has a ton of features!
My importer was horribly barebones - nice to see something with a lot more options.

Kyle had one too which had a lot more features - but this looks super!

Ahh so your XML changes let you navigate the XML structure without knowing the name / order? That looks very handy!

Will have to add it for 0062.

Theo

Hey Thanks Theo!
I didn’t knew there was something else then your ofxSVGLoader! Do you know where it is? I’ve search the forum before starting to write this one but I just found yours!

Anyway I’m glad you like it!

Ahh so your XML changes let you navigate the XML structure without knowing the name / order? That looks very handy!

Yes exactly, but it was more a “quick hack” than real usable code because I didn’t wanted to change things inside ofxXMLSettings! To make things fast and clean, you will have to change some stuffs! (But I will be glad to help!).
Anyway it works the same way, with the same syntax, except you only get strings so you’ll have to parse them outside of ofxXMLSettings…


Here’s some screenshots for the text:

Rendered with ofTruetypeFont:
[attachment=1:1qj93d3r]ofxSVGText_OF.png[/attachment:1qj93d3r]
Rendered with FTGL:
[attachment=0:1qj93d3r]ofxSVGText_FTGL.png[/attachment:1qj93d3r]

Ah, this is stellar. I’ve been trying to extend what theo had with my own stuff and it’s been going really slow. This is very timely. Thanks so much!

==== edit

just an update to this I had a bit of trouble getting automake to compile ftgl w/o the configure.in file, so I downloaded it myself made and archived a static library. If anyone else runs into problems, that’s probably an easy way to include it.

that sounds like a great feature, really dig the idea of building a UI from an svg file.
ive only been able to manually code UIs in OF in the past.
also this could potentially be an asset creation tool for OF in the same way that the Flash iDE is used to create assets and then the code takes over to manage the assets eg. add them to the stage and even perform simple animation.

very exciting!

[quote author=“simongeilfus”]Hey Thanks Theo!
I didn’t knew there was something else then your ofxSVGLoader! Do you know where it is? [/quote]

Here it is!
http://code.google.com/p/projectknave/s-…-ofxSvg/src

I was thinking about the xml stuff - might be nice to just extended ofxXmlSettings with your fixes/hacks so that people don’t need to change ofxXmlSettings to use it.

So in ofxSvg.h there is a class called ofxSvgXml that extends ofxXmlSettings with the stuff you need.

Theo

Great I’m going to check this tonight!

Yeah you are right, that would be a lot better!
I think I’m going to finish the parser and then re-think completly the design of the addon… Actually I started coding on Tuesday, and often when I code something from scratch very quickly I just make stupid designs!
So yes! I’m going to do this ofxSVGXml!

Yesterday, I struggled a bit to much to parse correctly the svg paths… and I was wondering… do you mind if I use the parts of your code related to path parsing, which are already working as expected?

Anyway, thanks for the suggestions!

Simon.

Of course - go for it!
Thats the whole point of open source right?

:smiley:

Hehe! yes indeed, but well, asking always make yourself more comfortable!
I got some free time today to continue the development, I’ll try to upload an update this afternoon!

@Julapy&Joshua: Thanks!

So!
Here’s a little update:

[attachment=0:2eq5qvrs]ofxSVG.zip[/attachment:2eq5qvrs]

I split the ofxSVG files into ofxSVG, ofxSVGXml and ofxSVGTypes for clarity…

Thanks to theo you don’t need to modify ofxXMLSettings anymore, but this is where my lack of experience in C++ makes me do weird stuffs! :slight_smile:

I tried to inherit the methods of ofxXMLSettings by adding the usual “: public ofxXmlSettings.h” but it doesn’t seems to be sufficient, so I had to copy every methods of the base class inside ofxSVGXml! I guess it’s the usual beginner mistake but I can’t find how to do it correctly!

There’s also a problem with how paths are rendered, I’m using theo’s code but as I’m not using any “shape date” object, I had to modify some stuffs, and now when you draw a path that is starting with a bezier, it’s not rendered correctly!

ofxSVG.zip

Thanks to theo you don’t need to modify ofxXMLSettings anymore, but this is where my lack of experience in C++ makes me do weird stuffs!

don’t know if this is your problem, but in c++ if you inherit from some class and have a method of the same name, although it has different parameters, you hide the methods in the base class, so for example in ofxSVGXml you have methods like getValue, getName, getAttribute that also exist in the base class.

to avoid this from happening you need to explicitly say that you want to use that methods in the base class like:

  
class ofxSVGXml : public ofxXmlSettings {  
public:  
    using ofxXmlSettings::getValue  
    using ofxXmlSettings::getName  
    using ofxXmlSettings::getAttribute  
    ....  

that way you’re going to be able to use the base methods implementations without rewritting them.

yes, c++ inheritance is weird :slight_smile:

hey! this does look great!

are there any plans to build save support in there? i’ve been working on a swappable rendering system so i can save a PDF that contains all of the content drawn by normal of* calls by switching the rendering system, but have run up against an issue in the lib i’m using that prevents complex images from being written out. not sure whether it’s a limitation of the lib or of the pdf format, but haven’t had a chance to check…

the existing codebase is here:
http://github.com/damiannz/openFramewor-…-ble-render

when you clone the repo you’ll need to also checkout the swappable_render branch, unfortunately i’ve forgotten how to do that but google can help. anyway i think it makes much more sense to be saving with SVG rather than PDF!

oh and simon: you want to be doing

“: public ofxXmlSettings”
not
“: public ofxXmlSettings.h”
:slight_smile:

Hey! Thanks Arturo!
I didn’t knew about that! It’s still weird but it’s working and now it’s much more short and clean like that! Thanks a lot! (Is it the only way to inherit from the base class methods? It should have a way to inherit of every public method by default! Or maybe this is a java misconception of inheritance, I don’t know!)

Damian: Great! A pdf Exporter!
Well I didn’t think about an option to save svg but it shouldn’t be that difficult as I already get all the “parsing stuffs”. Actually I’m currently discussing with Joshua about a good way to collaborate on this addon, I just created a google code svn, so if you have any ideas/suggestions about others features like that, don’t hesitate, I would really appreciate to hear them!

Oh, and what do you mean by “switching the rendering system”? Something like the last parameters of the size method of Processing? (size(800,600, PDF) ?)

I’d like to put save support in there, I don’t think it’d be too hard once we have the rendering working correctly. You could save out to an SVG, xml file, or a bitmap too. That might be a nice feature, kind of like the processing prosvg.

I fixed the path problem and added vertexs data for every types of shapes except ofxSVGText and ofxSVGPath. The code looks a bit more clean and is no more dependent on ofxXMLSettings. (You still need to download ofxDisplayList and ofxFTGLFont above).

There is still an issue with how ofTrueTypeFont renders the text … it seems like there’s a problem with font sizes! Font are rendered a bit too big and I think that the number passed as the size parameter is rounded somewhere… This mean that until I found a solution for that, rich texts (different size / fonts / colors inside the same text) must be rendered using FTGL.

I’m working on the opacity and the rotations so the renderer will be complete soon!

Here’s the link to the svn :

http://code.google.com/p/ofxsvg/source/-…-ofxSVG/src

and a zip:
[attachment=0:164wxgy9]ofxSVG.zip[/attachment:164wxgy9]

ofxSVG.zip

Little update:
ofxSVG is now supporting opacity too!

this sounds GREAT! but…
:? hm, i dont know how to install FTGL on my mac (snow leopard)…

EDIT: ok, changing all <FTGL/ftgl.h> to “ftgl.h” made it!

EDIT: Is there a way to antialiasing lines? Are images embeddable ?

We haven’t done images yet, unfortuanely. Anti-aliasing lines is also big on my list. I think Simon and I have both been really busy with other things, but I’m going to start back on this (finish VBO drawing and better save-to are close) so I’ll make sure that images get in there for sure.

Hi!

here some Text-Texts. I tried this text:

mak. HOFHEIM. Der Möbelkonzern Ikea sieht für sich noch Wachstumsmög- lichkeiten im Rhein-Main-Gebiet. Es gebe in diesem Ballungsraum Potential für ein weiteres Haus, sagte Armin Mi- chaely, Geschäftsführer der Ikea Verwal- tungs-GmbH, im Gespräch mit dieser Zei- tung. Der schwedische Konzern betreibt seit vielen Jahren Häuser in Hofheim-Wal- lau, wo zugleich der Deutschland-Sitz ist, und in Hanau. 2007 kam ein Haus im Frankfurter Stadtteil Nieder-Eschbach hinzu. Michaely sagte, es sei das Ziel, in etwa fünf Jahren ein viertes Haus in die- sem Ballungsraum zu eröffnen. „Wenn es die Möglichkeit dazu gibt, werden wir es tun.“ Auf eine Stadt mochte sich Michae- ly, Expansionsmanager in der Deutsch- land-Zentrale, nicht festlegen. Er erwähn- te allerdings als denkbaren Standort Frankfurt.
[attachment=2:2vpwwcil]text_1.png[/attachment:2vpwwcil]
[attachment=1:2vpwwcil]text_2.png[/attachment:2vpwwcil]
[attachment=0:2vpwwcil]text_3.png[/attachment:2vpwwcil]

greetings ascorbin