After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 760112 - rsvg_handle_get_(position|dimensions)_sub() returns wrong value
rsvg_handle_get_(position|dimensions)_sub() returns wrong value
Status: RESOLVED OBSOLETE
Product: librsvg
Classification: Core
Component: general
2.40.x
Other Linux
: Normal normal
: ---
Assigned To: Federico Mena Quintero
librsvg maintainers
: 739916 761264 761286 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2016-01-04 02:43 UTC by Jehan
Modified: 2017-12-13 18:13 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jehan 2016-01-04 02:43:52 UTC
For GIMP, we are moving towards SVG icons, and I am writing a script which extracts objects from a single SVG file by their id into a separate SVG file, and update the viewBox.

I use librsvg to extract the position and dimension of the objects. It works mostly well, but for some icons, I get very weird result and I am forced to recreate the icon from scratch.

Steps:
- download art-libre.svg from:
https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/art-libre-symbolic/src/art-libre.svg
- load it with librsvg's rsvg_handle_new_from_file().
- We will interest ourselves for instance in the Wilber icon (id #g39819). If you open the file art-libre.svg in Inkscape, you can check that object #g39819 has size 16x16.
- get the position for this object with rsvg_handle_get_position_sub()
- get the dimension with rsvg_handle_get_dimensions_sub()

Result: I should get dimensions 16x16, as Inkscape shows me. Instead I get very weird 278x211 dimensions. The returned position is very weird as well: (-363, 226), and it cannot be used to create a proper viewBox in any way.

There is a clear discrepancy between what Inkscape shows me and what librsvg returns. librsvg returns right values for most of the objects but there are still a bunch of them where it doesn't (for instance all the "stock-channel-*" icons as well in the same file).
Comment 1 Jehan 2016-01-04 21:33:16 UTC
So I have investigated a little more, and I have found at least 2 cases where rsvg_handle_get_(position|dimensions)_sub() return completely wrong results.

** Straight Paths **

For instance in art-libre.svg, the path id "path6469" is:

>         <path
>           inkscape:connector-curvature="0"
>           id="path6469"
>           d="m 45.0002,580 3,3 0,0"
>           style="fill:none;stroke:#bebebe;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />

Since I can see 2 translations (-241.0002,-217) and (20,0) in parent nodes, I would expect position of (-176, 363) and dimensions 4x4 (the stroke width being 1px).
Instead it returns me a position (-221, -217) for dimensions 48x583, which is absolutely broken.

If I add points keeping the path as a straight line, results are still crazy. Like adding the points 5,5, dimensions become 53x588 (so +5 on each dimension, which is right relatively to the previous result, yet still wrong in absolute).

But if I add a point changing the direction, for instance:

> d="m 45.0002,580 3,3 0.1,0.2"

I suddenly get the expected position (-176, 362) and dimensions 4x4!

** paths with a single points **

Some paths have a single point, which is likely mostly useless (well unless the stroke width is huge, I guess) but are not technically wrong.

For instance in art-libre.svg, you can find:

>           <path
>             inkscape:connector-curvature="0"
>             id="path5329-6"
>             d="M 269.08553,205.0946 z"
>             style="fill:none;stroke:#000000;stroke-width:0.99851286px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />

Again, considering translations on parent nodes, I expect position (-94, 431) and dimension 1x1.
Instead I get position (-363, 226) and dimensions 0x0. Well here the dimension is not too much a problem (not sure a "dot" of 1 pixel is that useful), but the completely wrong position makes computing dimensions of a parent out the charts if I try to export a parent node.

Once again adding 2 points (not as a straight line) works the bug around and librsvg returns the expected position.
Comment 2 Jehan 2016-01-28 21:42:26 UTC
I actually can find other cases. Like bug 761264.
Comment 3 Jehan 2016-01-29 13:20:14 UTC
Another case of wrong values: bug 761286.
Comment 4 Federico Mena Quintero 2017-08-29 22:43:34 UTC
*** Bug 761286 has been marked as a duplicate of this bug. ***
Comment 5 Federico Mena Quintero 2017-08-29 22:43:53 UTC
*** Bug 739916 has been marked as a duplicate of this bug. ***
Comment 6 Federico Mena Quintero 2017-08-29 22:44:48 UTC
*** Bug 761264 has been marked as a duplicate of this bug. ***
Comment 7 Federico Mena Quintero 2017-08-29 22:46:35 UTC
Hey, apologies for getting to this bug until now.  It's only recently that I found out that my bugzilla admin configuration was incorrect; I wasn't getting maintainer bugs for librsvg :( :( :(

I'm working on this.  https://bugzilla.gnome.org/show_bug.cgi?id=739916#c2 has an interesting analysis, and the comment before that one has some test conditions.
Comment 8 Jehan 2017-08-29 22:54:12 UTC
Hi Federico!

I was indeed wondering what was the status with librsvg especially since I read about the renewal of activity (yet no bugs were ever answered).

If all the various use cases could indeed be fixed, it would be great. Right now, in GIMP, I had simply given up on librsvg and we were exporting each icon by hand (and had to commit them in the repository). Having a working librsvg would change things. :-)

As for Massimo's comment, I indeed think he is on the right track, as always! :-)
Comment 9 Federico Mena Quintero 2017-08-30 01:52:22 UTC
Yes, indeed he is.  Changing bbox.rs to have

    if src.rect.width == 0.0 || src.rect.height == 0.0 {
        return;
    }

inside rsvg_bbox_insert() indeed makes the dimensions closer to what you expect.  However, they are not 16x16!  I'm trying to find out why.

I'd really like to clean up the "figure out the dimensions" code path.  Right now it is interwoven with the "render everything" code path, so either case also does the work of the other, which slows things down and is unnecessary.

The rsvg_handle_get_position_sub() and get_dimensions_sub() functions are not exacly what one wants, though.  Those are intended to be "give me the size/position in pixels", as they return ints.  Right now it is not defined whether those pixels in fact allow for full coverage of the rendered region, or whether there is less-than-a-pixel left over.

I'm changing them to return the pixel for full ink coverage.

Maybe we can have extra APIs to get the ink rectangle and the logical rectangle (for the "fill:none; stroke:none" trick from icon sets), in floating point numbers.
Comment 10 Federico Mena Quintero 2017-08-30 02:23:47 UTC
I'm putting this work-in-progress in this branch:

https://github.com/federicomenaquintero/librsvg/tree/fix-dimensions

If you could play with it, it's much appreciated :)  It has the bbox fix described above, plus patches based on your bug #762039.

You can run

./tests/dimensions -p "/dimensions/sub/bug760112-wilber"

to watch that test fail.  It will spit logging info; I don't understand yet why it's computing w=18 h=16 instead of 16x16.
Comment 11 Jehan 2017-08-30 09:06:13 UTC
> I don't understand yet why it's computing w=18 h=16 instead of 16x16.

I have not looked at your new code and the svg file, so I will make a wild guess. Have you added the logical dimension function you talk about in bug 762039, comment 13?

Because if you floor the pixel on one side, and ceil it on the other, you could easily add 2 pixels!
Imagine your icon is comprised in [0.99; 17.01] which is a dimension of 16.02 pixel (slight error of 0.02px; these kinds of things unfortunately happen much too often in Inkscape even when you give accurate pixel sizes and snapping), then by flooring/ceiling, you'd get [0; 18] hence a 18px.

This is why it is just important to get accurate double positions/dimensions. The part of bug 762039 where I ceil/floor values to get int dimensions/positions was only because I was asked to. But in the end, I seriously don't care much. It's a little less wrong, but just as useless for clean extraction. We want double! :-)

Now maybe that's not the problem and there is an actual other bug here. :-)
Comment 12 GNOME Infrastructure Team 2017-12-13 18:13:50 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/librsvg/issues/128.