svg / svgo

⚙️ Node.js tool for optimizing SVG files
https://svgo.dev/
MIT License
21.08k stars 1.39k forks source link

convertTransform changes gradientTransform and breaks file #1268

Open JoKalliauer opened 4 years ago

JoKalliauer commented 4 years ago

Input

SVG: https://gitlab.com/inkscape/inbox/uploads/38f99130aaaac8c6f93d13023a212604/Input.svg

Output

SVG: https://gitlab.com/inkscape/inbox/uploads/5674e73587bcb2e07f267244349914d1/Output.svg

Differences

changes

Copyright

source: https://commons.wikimedia.org/wiki/File:Hematopoiesis_(human)_diagram_en.svg

JoKalliauer commented 1 year ago

Because it is difficult to see the difference I make a minimal (not) working example

Input-SVG

Input1268

Output-SVG

Output1268

Input-Code

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" font-family="'Liberation Sans', Arial" viewBox="0 0 96 42">
  <radialGradient xlink:href="#a" id="d" cx="0" cy="0" r="819.2" gradientTransform="matrix(.001 .001 -.002 .002 85.201 25.541)"/>
  <radialGradient xlink:href="#b" id="e" cx="0" cy="0" r="819.2" gradientTransform="matrix(.004 .023 -.028 .005 23.901 19.641)"/>
  <radialGradient xlink:href="#c" id="f" cx="0" cy="0" r="819.2" gradientTransform="matrix(.001 .002 -.002 .001 29.401 9.9406)"/>
  <linearGradient id="b" gradientUnits="userSpaceOnUse">
    <stop offset=".9" stop-color="#d0c2dd"/>
    <stop offset="1" stop-color="#c2a0e4"/>
  </linearGradient>
  <linearGradient id="c" gradientUnits="userSpaceOnUse">
    <stop offset=".2" stop-color="#fefefe"/>
    <stop offset=".5" stop-color="#f0ebf4"/>
    <stop offset="1" stop-color="#d0c2dd" stop-opacity="0"/>
  </linearGradient>
  <linearGradient id="a" gradientUnits="userSpaceOnUse">
    <stop offset=".2" stop-color="#ddbbfd"/>
    <stop offset=".7" stop-color="#bd7bff"/>
    <stop offset="1" stop-color="#aa54ff" stop-opacity="0"/>
  </linearGradient>
  <path fill="#aa64ed" stroke="#9139e9" stroke-linecap="round" stroke-linejoin="round" stroke-width=".5" d="M75 22v1l-1-2h-1zm-2-1c-1-2-4-2-6-3-4 0-6 0-8 2-1 2-2 5 0 7 1 3 2 5 4 6 4 3 8 4 13 4s8 0 12-2 4-4 5-8a12 12 0 0 0-2-6l-3-6a14 14 0 0 0-10-6c-5-1-8 1-9 3-1 3 0 5 1 6l2 1 1 2z"/>
  <path fill="url(#d)" d="m86 24 1 1-1 2h-1c-1 1-1 0-2-1l1-1 1-1h1z"/>
  <path fill="url(#e)" d="M47 15a21 21 0 0 1-20 24 28 28 0 0 1-17-3 19 19 0 0 1-9-12c-2-5 0-10 4-15s9-7 16-8c6-2 12-1 17 2 5 2 8 7 9 12z"/>
  <path fill="url(#f)" d="M28 11V9l1-1c2 0 2 1 2 2v1h-3z"/>
</svg>

Output-Code

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" font-family="'Liberation Sans', Arial" viewBox="0 0 96 42">
  <radialGradient xlink:href="#a" id="d" cx="0" cy="0" r="819.2" gradientTransform="translate(85.201 25.541) scale(.001 .004)"/>
  <radialGradient xlink:href="#b" id="e" cx="0" cy="0" r="819.2" gradientTransform="matrix(.004 .023 -.028 .005 23.901 19.641)"/>
  <radialGradient xlink:href="#c" id="f" cx="0" cy="0" r="819.2" gradientTransform="rotate(60 3.808 27.497) scale(.002)"/>
  <linearGradient id="b" gradientUnits="userSpaceOnUse">
    <stop offset=".9" stop-color="#d0c2dd"/>
    <stop offset="1" stop-color="#c2a0e4"/>
  </linearGradient>
  <linearGradient id="c" gradientUnits="userSpaceOnUse">
    <stop offset=".2" stop-color="#fefefe"/>
    <stop offset=".5" stop-color="#f0ebf4"/>
    <stop offset="1" stop-color="#d0c2dd" stop-opacity="0"/>
  </linearGradient>
  <linearGradient id="a" gradientUnits="userSpaceOnUse">
    <stop offset=".2" stop-color="#ddbbfd"/>
    <stop offset=".7" stop-color="#bd7bff"/>
    <stop offset="1" stop-color="#aa54ff" stop-opacity="0"/>
  </linearGradient>
  <path fill="#aa64ed" stroke="#9139e9" stroke-linecap="round" stroke-linejoin="round" stroke-width=".5" d="M75 22v1l-1-2h-1zm-2-1c-1-2-4-2-6-3-4 0-6 0-8 2-1 2-2 5 0 7 1 3 2 5 4 6 4 3 8 4 13 4s8 0 12-2 4-4 5-8a12 12 0 0 0-2-6l-3-6a14 14 0 0 0-10-6c-5-1-8 1-9 3-1 3 0 5 1 6l2 1 1 2z"/>
  <path fill="url(#d)" d="m86 24 1 1-1 2h-1c-1 1-1 0-2-1l1-1 1-1h1z"/>
  <path fill="url(#e)" d="M47 15a21 21 0 0 1-20 24 28 28 0 0 1-17-3 19 19 0 0 1-9-12c-2-5 0-10 4-15s9-7 16-8c6-2 12-1 17 2 5 2 8 7 9 12z"/>
  <path fill="url(#f)" d="M28 11V9l1-1c2 0 2 1 2 2v1h-3z"/>
</svg>
SethFalco commented 10 months ago

I'm reopening this, as it does partially resolve the issue, but there are still some changes in the test file provided.

johnkenny54 commented 10 months ago

It looks like the problem here is that there's code in convertTransform that limits the precision of the decomposition to no more than the maximum number of decimal digits in the matrix - in this case, the matrix entries are all 3 digits, so it is changing precision from 5 to 3. The comment in the code says "Calculating with larger precision doesn't add any value", but that's clearly not true in this case. If this code is removed, everything seems OK. I'll look in to what effect removing this limit has.

SethFalco commented 10 months ago

Ahh, so it's the same issue as this, then:

https://github.com/svg/svgo/issues/1810#issuecomment-1773948756

johnkenny54 commented 10 months ago

Partially. There are a number of issues with rounding. With the default config, what I see when I make this change is:

There are several other issues that are improved, but not fully resolved: #988, #1021, #1222

I'll check this against the full set of regression files, assuming nothing bad happens there I'll create a PR.