titles and descriptions lost when saving as Plain SVG

Bug #249445 reported by sas
6
Affects Status Importance Assigned to Milestone
Inkscape
Fix Released
Undecided
codedread

Bug Description

Saving a file as Plain SVG loses 'title', 'desc' and 'metadata' elements that are children of 'rect', 'path', 'image', etc., elements. This happens because the write methods that produce the plain SVG don't expect such elements to have any children.

To reproduce:

  (1) Draw a rectangle (or whatever).
  (2) Add a title and description (right click, Object Properties, etc.).
  (3) Save the file as Plain SVG.
  (4) Open the plain SVG file, and check the Object Properties dialog for the object - the title and description will not be there.

Revision history for this message
sas (sas-sas) wrote :

I think that sp_item_write() in src/sp-item.cpp needs to be modified so that if (flags & SP_OBJECT_WRITE_BUILD) then child nodes are written. But this will cause the content of groups to be written twice, so the code that writes child nodes in sp_group_write() needs to be removed. Is this all that needs to be done?

Revision history for this message
bbyak (buliabyak) wrote : Re: [Bug 249445] Re: titles and descriptions lost when saving as Plain SVG

No. I don't think this is right. You just need to create SPObject
types for the metadata elements, and in them you need to create _write
methods that check the flags and create new reprs for the plain svg
copy of the tree. In short, just track how a regular element like
svg:path is not lost in plain svg, and reproduce the same pipeline for
the metadata ones.

Revision history for this message
codedread (codedread) wrote :

Just to understand a little more - bbyak, do you know why svg:text elements keep their svg:title and svg:desc upon saving as Plain SVG? Thanks.

Revision history for this message
bbyak (buliabyak) wrote :

On Mon, Jul 28, 2008 at 7:06 PM, codedread <email address hidden> wrote:
> Just to understand a little more - bbyak, do you know why svg:text
> elements keep their svg:title and svg:desc upon saving as Plain SVG?

because sp_text_write has a loop on all children:

        for (SPObject *child = sp_object_first_child(object) ; child
!= NULL ; child = SP_OBJECT_NEXT(child) ) {

which recreates the repr of each child if flags & SP_OBJECT_WRITE_BUILD

Revision history for this message
codedread (codedread) wrote :

So I implemented SPObject types for title and desc elements. However, I'm having trouble getting Inkscape to output them using Plain SVG. As an example, let's look at sp-rect.cpp:

static Inkscape::XML::Node *
sp_rect_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
...
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:rect");
    }
...
    if (((SPObjectClass *) parent_class)->write)
        ((SPObjectClass *) parent_class)->write(object, xml_doc, repr, flags);

    return repr;
}

As you can see, for each shape we create a new XML rect element (that does not contain its children). This is the same for other elements (path, circle, whatever).

So how to get Inkscape to copy the rect's title and desc children? Should I add code to sp-object's write function to grab its children and then duplicate and add them? If so, should I only do this for svg:title and svg:desc children? If so, then I guess I'd have to modify the code in sp-text and sp-item-group that already grab the children?

I will be in freenode's irc channel to discuss this if either of you are around today.

Revision history for this message
codedread (codedread) wrote :

Of course the other option seems to be to add code in every one of the object type's write methods to get the title/desc children - but that seems like even more work.

Revision history for this message
codedread (codedread) wrote :

This is a patch for the bug, taking bbyak's suggestions. I introduced new SPObject types for desc and title elements. I also removed many existing element's serialization of their child nodes and moved this into the sp-item's write method. Now all methods preserve their children when saving as Plain SVG.

I'm a bit leery about this patch since it is pretty large (my previous patches are a few lines each) so if someone can test this before committing, I'll feel better.

Revision history for this message
codedread (codedread) wrote :

This is a new patch that obsoletes my first patch. The new patch (#2) also:

- fixes a segfault (group's write was not creating a svg:g in Plain SVG case)
- updates several SPObject type write methods that I missed the first time (flowRegion, flowRoot, flowPara, flowTspan, etc)

So the problem that I see it now with the patch that I've implemented is:

- item does all the serializing of child objects (for both Plain SVG and Inkscape SVG), whereas before SPObject subclasses would only specify the types of children it could have in Plain SVG mode
- for instance, before my patch, flowDivs would only allow: flowTSpan, flowPara or strings for Plain SVG
- after my patch, all children types are allowed for flowDivs
- this is why I've left that code in the various write methods and simply commented it out (not convinced I should be removing it)

We want object types to be able to say what child types are allowed in Plain SVG mode (we just don't want to add a loop in every subclass that will specifically allow <title> and <desc> children).

I think the only solution is to restore the child-looping code in the subclasses that have it but also add child-looping code into sp-item that explicitly allows <title> and <desc> to be prepended. This means we loop over the children twice for those types that have other types of children outside of <title> and <desc>. Not too big of a deal tho.

Will work on this and submit a subsequent patch (#3).

Revision history for this message
codedread (codedread) wrote :

Only possible hitch in my proposed final solution is that some elements (<g> and <text>) had code that allowed any child type. If I'm going to put code into sp-item to write <title> and <desc> in Plain SVG mode, I need to explicitly disallow the serializing of <item> and <desc> in <g>'s write method.

Revision history for this message
codedread (codedread) wrote :

Ok, patch #3 that obsoletes all others. This patch puts all of the child-crawling code back into the sub-classes and guards against title/desc when necessary. Then, there is child-crawling code in sp-item's write method that only serializes title/desc elements. I've tested this on rect, text and flowtext saving in both Inkscape SVG and Plain SVG and it seems to work as expected.

Revision history for this message
codedread (codedread) wrote :

Committed patch.

Changed in inkscape:
status: New → Confirmed
assignee: nobody → codedread
status: Confirmed → Fix Committed
jazzynico (jazzynico)
tags: added: metadata saving
Changed in inkscape:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.