cppfw/svgdom

Adding namespaces to root <svg> and other questions about writing SVGs to XML

Closed this issue · 1 comments

I am using svgdom to generate and update a DOM dynamically from code (instead of loading the svg file) and then generate the corresponding XML string. I have some questions and suggestions:

Adding namespaces to the root <svg> element

Is there a way to include namespaces when writing the root <svg>? Here's the code and the generated string to illustrate what I'm talking about:

auto dom = utki::makeUnique<svgdom::SvgElement>();

svgdom::PathElement path;

svgdom::PathElement::Step step;

step.type = svgdom::PathElement::Step::Type_e::MOVE_ABS;
step.x = 0;
step.y = 0;
path.path.push_back(step);

step.type = svgdom::PathElement::Step::Type_e::LINE_ABS
step.x = 0;
step.y = 300;
path.path.push_back(step);

step.type = svgdom::PathElement::Step::Type_e::LINE_ABS;
step.x = 300;
step.y = 300;
path.path.push_back(step);

step.type = svgdom::PathElement::Step::Type_e::LINE_ABS;
step.x = 300;
step.y = 0;
path.path.push_back(step);

dom->children.push_back(utki::makeUnique<svgdom::PathElement>(path));

cout<<dom->toString()<<std::endl;

And here's the string result:

<svg>
	<path d="M0,0L0,300 300,300 300,0"/>
</svg>

Notice that the xmlns namespace is missing, and therefore the result can't be properly rendered.

Streams for custom strings (to write unsupported elements)

Let's say that I am generating an XML string, and I want to write an element that is unsupported by svgdom (eg: <filter> or <pattern>). Would it be possible to write a custom string in order to add any element that might be unsupported or maybe even to just add some comments?

I am actually planning to add a new element called StringElement whose sole purpose is add any extra text to the XML string. What do you think?

Unique pointers

Using unique_ptr and utki::Unique makes the construction of DOMs a bit convoluted, and it can be confusing for users that don't understand the concept of unique pointers. It would be much easier to write something dom.push_back(path) instead of dom->children.push_back(utki::makeUnique<svgdom::PathElement>(path)) . Is it really necessary to force the unique pointers? Why are unique pointers needed?

Constructors and structs

I am considering adding constructors to some elements to allow the initialization of some attributes. It would be great to initialize the vector of steps right on the constructor for the PathElement for example. What do you think?

And finally, just out of curiosity: why do you use structs for the elements instead of classes?

@igagis you mentioned that writing SVGs to XML is not critical, but I believe that it's a really useful feature and it's almost ready ;). Supporting symmetric reading/writing operations is what I like about svgdom since I can modify the DOM dynamically and generate the XML strings on the fly. I can help, but first I am trying to understand some of your architecture decisions.

  1. Adding namespaces to the root <svg> element there should be namespaces added, no idea why those are not added in your case. Please open a separate bug for that if you still see that problem with latest version.

  2. Streams for custom strings (to write unsupported elements) <filter> and <pattern> elements are not custom elements, i.e. those are in SVG spec. Please submit a separate bug to add a support for them into svgdom. As for totally custom elements, you can derive your own elements from svgdom::Element and add those to dom tree. But I'm not sure how flexible the API currently is to allow performmig specific actions when traversing through the dom tree. Please also open a seprate bug for that problem, i.e. possibility to extend the dom structure, and describe the scenario you would like to be possible to do with it.

  3. unique_ptr's are needed for memory management. There can be convenience methods added to the classes. Same here, please open a separate bug for that.

  4. Convenience constructors can be added. Open separate bug for that.

  5. structs are used because this library is mainly a DOM, meaning that there is no intention to encapsulate any data or add any logic, it is only a tree of elements holding necessary data.

  6. Writing XML is a good feature, I just didn't need it for my own purposes at first, so I added a simple generation of XML just for testing. Please open a separate bug for adding a proper design for writing XML.