SVG processed differently depending on program context

Bug #1348417 reported by David Mathog
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Inkscape
Fix Released
Medium
David Mathog

Bug Description

While working on bug #1340683 it became apparent that a test SVG processed through createNewDocFromMem (in emf-inout.cpp) was not producing the same final document that same SVG read in from a file.

The SVG in question uses clipping.

The problem is that when it is processed through the first path the coordinates of the <text> objects are scaled absolutely, yet these refer to the same clip-path, and its coordinates are not modified. So the text no longer matches its clipping object. Conversely, where <path> objects reference a clipping object they still work, because they retain their original coordinates, but have a "transform=" added. So for a path the clip goes correctly, using the original coordinates, but the final result is then scaled via the transform to land in the appropriate place.

When the SVG is processed from a file it is not scaled, so there are no mismatch issues.

Revision history for this message
David Mathog (mathog) wrote :
Revision history for this message
David Mathog (mathog) wrote :
Revision history for this message
David Mathog (mathog) wrote :

This is the EMF test file which turned up this bug. As of revision 13468 when this EMF file is processed by emf-inout.cpp the result is the data that was stored in "mangle_clip.svg". When this data is passed to createNewDocFromMem() in Emf::Open the result is "mangled_clip.svg". When the current bug is resolved reading this EMF test file should result in a final SVG file that looks like "mangle_clip.svg", although it might differ slightly in the internal details.

Revision history for this message
David Mathog (mathog) wrote :

This bug was observed on Linux, it has not yet been tested on Windows.

su_v (suv-lp)
tags: added: clipping text transformations
Revision history for this message
David Mathog (mathog) wrote :

This patch makes the same changes as above but for WMF input files. It also includes a slight correction for clipping path names, so that clipping paths from EMF and WMF have different names. Committed as revision 13473. As before, bug #1348417 messes up the generated SVG, but one can see that it was correct if the debug line in Wmf::open is uncommented, to copy the generated SVG to stdout, and then read it back in as a normal SVG file.

Revision history for this message
David Mathog (mathog) wrote :

Oops, sorry, the preceding post went into the wrong bug. It should have been in bug #1340683.

Revision history for this message
Liam P. White (liampwhite) wrote :

This bug is related to bug #1317050

Revision history for this message
David Mathog (mathog) wrote :

This bug is really a problem for people who use EMF input files. It escapes me why processing of SVG input should differ in any way depending on whether it is read from memory or read from a file. I am sorely tempted to replace createNewDocFromMem() with code that writes a temporary file and then uses the usual file read SVG input method. That will give it the name of the temporary file, but at least it will have clipping that works!

Revision history for this message
David Mathog (mathog) wrote :

status report:

Hacked up the local copy of createNewDocFromMem() so that instead of reading from memory it opens a hardwired file name. That is then passed to createDoc(). That is:

      Inkscape::XML::Document rdoc = sp_repr_read_file("/tmp/simple.svg", SP_SVG_NS_URI);

instead of

    Inkscape::XML::Document *rdoc = sp_repr_read_mem(buffer, length, SP_SVG_NS_URI);

A file "simple.svg" passed in that way is processed incorrectly. The same file opened with open->file is processed correctly.
In both cases, as far as I can tell processing passes through createDoc() with _exactly_the_same_data_ in the call. The problem is that clipping paths (and who knows what else) in defs is not scaled by something createDoc() calls, but text and paths in the main part are. Consequently clipping breaks because the clipping object no longer matches the clipped object.

Conclusion - at the present time createDoc() has either indeterminate output or output that depends upon some program context which is not well documented. In particular, there is nothing about this behavior noted anywhere near createDoc() in document.cpp.

Also tried: adding a doc->ensureUpToDate() immediately after createDoc(), because that has resolved some other mysterious bugs. It did not help here.

Revision history for this message
David Mathog (mathog) wrote :

More information for debugging.

run it like:

gdb --args src/inkscape /tmp/small_test.svg
break document.cpp:300
run
bt

#0 SPDocument::createDoc (rdoc=0x8f6b4f0, uri=0x8c8ad48 "\354\017\310\b\354\254\310\b\\a\310\b\\k\275\b\\k\275\b\240\017\306\bȟ\315\b\001", base=0x98aff10 "/tmp/",
    name=0x8c8ad48 "\354\017\310\b\354\254\310\b\\a\310\b\\k\275\b\\k\275\b\240\017\306\bȟ\315\b\001", keepalive=1, parent=0x0) at document.cpp:331
#1 0x080e8d11 in SPDocument::createNewDoc (uri=0x8e4a42c "/tmp/small_test.svg", keepalive=1, make_new=false, parent=0x0) at document.cpp:556
#2 0x082c61d8 in Inkscape::Extension::Internal::Svg::open (this=0x8ca4f40, uri=0x8e4a42c "/tmp/small_test.svg") at extension/internal/svg.cpp:198
#3 0x082bc623 in Inkscape::Extension::Input::open (this=0x8ca5d50, uri=0x8e4a42c "/tmp/small_test.svg") at extension/input.cpp:153
#4 0x082ba238 in Inkscape::Extension::open (key=0x8c8ad48, filename=0x8e4a42c "/tmp/small_test.svg") at extension/system.cpp:117
#5 0x08101010 in sp_file_open (uri=..., key=0x0, add_to_recent=true, replace_empty=true) at file.cpp:274
#6 0x080ad76e in sp_main_gui (argc=2, argv=0xbffff6d4) at main.cpp:1065
#7 0x0808c321 in main (argc=2, argv=0xbffff6d4) at main.cpp:789

Attached is a simpler test case. When loaded from the SVG form as above it displays properly and the 2nd line of text (black on white) is shown. When loaded from emf (converted to the exact same SVG and loaded from createDocFromMem()) and the second line is not shown.

Revision history for this message
David Mathog (mathog) wrote :

SVG form of the test file. This is the text that is sent into createDocFromMem() inside emf-inout.cpp.

Note, due to font substitution the Asian characters may not look right on many systems. The numeric text should be OK though. The 2nd line's first numeric value is "208.6".

Revision history for this message
David Mathog (mathog) wrote :

Note that this does not open properly (it drops the 2nd line):

 gdb --args src/inkscape /tmp/small_test.emf

with bt

#0 SPDocument::createDoc (rdoc=0x8f6b4f0, uri=0x8c8ad48 "\354\017\310\b\354\254\310\b\\a\310\b\\k\275\b\\k\275\b\240\017\306\b8\237\315\b\001", base=0x0,
    name=0x8c8ad48 "\354\017\310\b\354\254\310\b\\a\310\b\\k\275\b\\k\275\b\240\017\306\b8\237\315\b\001", keepalive=1, parent=0x0) at document.cpp:331
#1 0x080e8bb9 in SPDocument::createNewDocFromMem (buffer=0x8c8ad48 "\354\017\310\b\354\254\310\b\\a\310\b\\k\275\b\\k\275\b\240\017\306\b8\237\315\b\001",
    length=147369288, keepalive=150102000) at document.cpp:577
#2 0x083366d3 in Inkscape::Extension::Internal::Emf::open (this=0x8c19310, uri=0x8e53a5c "/tmp/small_test.emf") at extension/internal/emf-inout.cpp:3500
#3 0x082bc623 in Inkscape::Extension::Input::open (this=0x8ca6098, uri=0x8e53a5c "/tmp/small_test.emf") at extension/input.cpp:153
#4 0x082ba238 in Inkscape::Extension::open (key=0x8c8ad48, filename=0x8e53a5c "/tmp/small_test.emf") at extension/system.cpp:117
#5 0x08101010 in sp_file_open (uri=..., key=0x0, add_to_recent=true, replace_empty=true) at file.cpp:274
#6 0x080ad76e in sp_main_gui (argc=2, argv=0xbffff6d4) at main.cpp:1065
#7 0x0808c321 in main (argc=2, argv=0xbffff6d4) at main.cpp:789

When run in valgrind I could not find any evidence of an uninitialized variable in any of the relevant sections.

Revision history for this message
David Mathog (mathog) wrote :

Changed name from

   SVG processed differently from memory and file

to

  SVG processed differently depending on program context

summary: - SVG processed differently from memory and file
+ SVG processed differently depending on program context
su_v (suv-lp)
Changed in inkscape:
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
David Mathog (mathog) wrote :

Progress. If the call to setViewBoxIfMissing() in emf-inout.cpp AFTER the createDocFromMem() is commented out then the SVG produced is identical to what it would be if the SVG is read in from a file. That is, no viewbox is defined when the
SVG is saved. So createDoc vs. createDocFromMem() is a red herring, the problem happens after those calls.

I do not recall why/when setViewBoxIfMissing was added, but its internals are mostly the same as DocumentProperties::onDocUnitChange() in document-properties.cpp.

Both of these do this (in slightly different ways):

        doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh));

If getRoot() does not include defs, or for some reason it skips the defs, then it explains perfectly why the emf input objects no longer match the defs.

Revision history for this message
David Mathog (mathog) wrote :

The attached patch resolves the EMF/WMF import issue. It may break something else. The method scaleChildItemsRec() was modified to apply the scaling at the group level and not to recurse into the group and apply it singly to the child items. There were no other changes. With that patch in place all tested incoming clip's from EMF worked in the SVG.

Before committing this we need to know WHY it was doing it the other way, since at the SVG level setting the transform on the group results in the same coordinates as setting the transform on each of the items in the group. I think that code has something to do with changing the units on a drawing, but I am not familiar enough with it to know what to look for in terms of bugs this change might have introduced.

Revision history for this message
David Mathog (mathog) wrote :

Note: clipping is currently still import only from EMF and WMF. Roundtrip testing does not work cleanly because the clipping is lost going from SVG to EMF/WMF.

su_v (suv-lp)
Changed in inkscape:
assignee: nobody → David Mathog (mathog)
milestone: none → 0.91
status: Confirmed → In Progress
Revision history for this message
David Mathog (mathog) wrote :

Patch committed in revision 13544, see further notes under bug #1302857 post 7.

Changed in inkscape:
status: In Progress → Fix Committed
Revision history for this message
su_v (suv-lp) wrote :

Regression introduced AFAICT with r13544:
http://sourceforge.net/p/inkscape/mailman/message/32801833/

Bryce Harrington (bryce)
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.