SVG transform matrix() arg order is a1 b1 a2 b2 a3 b3, not a1 a2 a3 b1 b2 b3

Bug #722544 reported by Johan Sundström on 2011-02-21
This bug affects 1 person
Affects Status Importance Assigned to Milestone
scour (Ubuntu)

Bug Description

This makes all of the transform="matrix(...)" tests not work as intended (and some of them were subtly broken in other ways too). I took a stab at brushing up on a little python, and pushed a branch ~ecmanaut/transform with some fixes, and half of the work towards some good test cases for all of it.

I'm still rather fresh on the language, so I didn't write the classes corresponding to the fifteen unittests/transform-*.svg files, but if anyone wants to pick up from where I left off, the tests for that code would be that a PASS for each file corresponds to coming up with the same existence and value of the "transform" attribute for the file's first "line" element, as the second one has.

On second thought, it might be wiser hiding the "correct" answer in an inline comment, in case both get squashed to something incorrect but equal.

(My loose plans are to get back to this code and replace all the FIXME:s I added with code, but I have no idea of if and when it might happen.)

codedread (codedread) wrote :

Thanks Johan - this definitely looks like a big bug.

Louis, for your reference:

Looks like this has been in the code since r172, which is unfortunate. Do you think you can take a look at Johan's branch and merge it into the trunk? Definitely we need lots and lots of unit tests for this type of function :)

Changed in scour:
importance: Undecided → High
assignee: nobody → Louis Simard (louis-simard)
Johan Sundström (ecmanaut) wrote :

As I don't write a lot of python and don't know what python constraints should be adhered to (I specifically believe I might have introduced 2.5/2.6:isms like the ternary operator), it might be worth testing, vetting and maybe changing that if scour should run on python 2.4 too.

For unit tests, we usually encode the correct answer in the test class and have only 1 element in the SVG file. I'll see what I can come up with.

Changed in scour:
status: New → Confirmed

I don't see any uses of anything that could look like a ternary operator in your patch. Maybe you wrote code then trashed it, or used a ternary operator in another Python project?

In any case, the code looks clean, but I'll change the unit test files a bit and make some test classes.

Changed in scour:
status: Confirmed → In Progress

Unit tests are written and are in lp:~scouring/scour/transform ; 6 fail with a TypeError generated by the new code, and 3 fail with an AssertionError created by incorrect output.

The TypeError is fixed by casting to float for math.asin.

Some other miscellaneous things, such as rotate(-300) rotate(-60) from the unit tests not becoming rotate(0), are also fixed.

This bug should be fixed in the trunk, as revision 207 (merge, 9 subrevisions).

Changed in scour:
status: In Progress → Fix Committed
Johan Sundström (ecmanaut) wrote :


I pushed another little set of rotate unit tests (and angle optimization) I wanted to do to lp:~ecmanaut/scour/transform – a bit too modest an optimization to merit a blueprint or ticket for itself, I think.

I've added your new code in as revision 208 as is. I'm not sure if anges in the range [270, 350[ should be automatically converted to the negative form, though, because:
 - negative angles are less intuitive to some people (less of an issue since Scoured files are not intended to be read by humans, although it helps to be able to read through them);
 - [270, 350[ maps to the range ]-10, -90], which takes the same number of characters to represent;
 - having a negative sign more often may upgrade the character - in the Huffman tables of .svgz files at the expense of the digits or some letters, thus reducing compression efficiency.

I may revisit this later and change that behavior. Thanks for your code submissions :)

Johan Sundström (ecmanaut) wrote :

Interesting points – I was mostly fighting the feeling that the "intuitive pick" for a angle domain was ]-180, 180], decided for myself that the win when mapping the [-180, -100] range to [180, 260] was worth it despite moving out of the "more intuitive" clockwise or counter-clock-wise rotations (and choosing, slightly arbitrarily, that -90 was a better cut-off point than -10, for human-intuition reasons). :)

There are certainly arguments many ways possible around this; some of which might be best inspected by taking a large sample of svg:s in the wild and running some stats on what's commonly used / generated by commonly used svg-generating tools. But that's another ballpark of work than coming up with clever optimizations. :)

Scour is fun!

Johan Sundström (ecmanaut) wrote :

Speculating successfully about svgz compression is usually hard, by the way; in real tests it can turn out that normalizing a file that uses both -90 and 270 interchangeably results in a more common keyword match, whether we normalize both to -90 or 270, as long as we normalize them at all – so try using a repository of real-world data for crunching out aggregate gains and losses using different algorithms if you're interested in good data on compression effects.

I've experienced enough peculiarities with gzip not to speculate too hard on what effect changes on input data will have on output data from gzip – like a large web page with inline normal javascript compressing to less than the same page with minified javascript, after gzipping both.

(So if we ever try doing something like a special mode for producing optimally small svgz files, a gz whiz should probably look into the optimal kind and location of redundant data to inject to make the gzip dictionaries favourable for reducing end size, which is yet again another radically different problem to tackle. :)

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package scour - 0.25+bzr207-1

scour (0.25+bzr207-1) unstable; urgency=low

  * New upstream bzr snapshot:
    - Add the option --no-renderer-workaround.
    - Fix gradient corruption. (LP: #702423)
    - Add option to only remove autogenerated id's. (LP: #492277)
    - Fix Windows line ending handling. (LP: #717826)
    - Fix occasional production of empty defs. (LP: #717254)
    - Remove more attributes with default values. (LP: #714731)
    - Fix wrong handling of file:// references. (LP: #708515)
    - Delete text attributes from groups with only non-text elements.
      (LP: #714727)
    - Remove unnecessary text-align properties from non-text elements.
      (LP: #714720)
    - Fix wrong optimization of 0-length Bézier curves. (LP: #714717)
    - Fix decimal number processing in rule_elliptical_arc(). (LP: #638764)
    - Fix transform matrix order. (LP: #722544)
  * Drop 01-bzr195.patch, upstream now.
  * debian/cmpsvg: Fix computation of difference to add up the absolute
    difference of each pixel.
  * debian/cmpsvg: Show percentages with three digits after comma.
  * debian/cmpsvg: Lower default treshold to 0.05%.
 -- Martin Pitt <email address hidden> Tue, 15 Mar 2011 09:28:45 +0100

Changed in scour (Ubuntu):
status: New → Fix Released

This bug is fixed in release 0.26 of Scour.

Changed in scour:
status: Fix Committed → Fix Released
jazzynico (jazzynico) wrote :

Fixed in inkscape trunk revision 10785.

Changed in inkscape:
assignee: nobody → JazzyNico (jazzynico)
importance: Undecided → Low
milestone: none → 0.49
status: New → Fix Committed
jazzynico (jazzynico) on 2015-02-14
Changed in inkscape:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers