lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
28.87k stars 1.29k forks source link

Convert SVG to PNG/JPG: When SVG2 line element is using `marker-end` with `orient="auto-start-reverse"` #2459

Closed ChaddFrasier closed 1 week ago

ChaddFrasier commented 3 years ago

Issue

Given an SVG file with line elements and marker-end attributes. The resulting PNG or JPEG file when converting using .png() or .jpeg() has incorrect orientation of the marker when using orient="auto-start-reverse"

test.svg 🔽

<?xml version="1.0" encoding="UTF-8"?>
     <svg viewBox="0 0 1500 1500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/2000/svg" version="1.1" width="1500" height="1500" preserveAspectRatio="xMidYMid meet" oncontextmenu="return false;">
          <defs>
           <marker id="line308-marker" viewBox="0 0 10 10" markerWidth="5px" markerHeight="5px" refX="0.1" refY="2.5" orient="auto" data-cy="markerhead">
                <path d="M 0 0 L 5 2.5 L 0 5" fill="white" stroke-width="2"/>
           </marker>
           <marker id="line308-markerEnd" viewBox="0 0 10 10" markerWidth="5px" markerHeight="5px" refX="0.1" refY="2.5" orient="auto-start-reverse" data-cy="markertail">
                    <path d="M 0 0 L 5 2.5 L 0 5" fill="white" stroke-width="2"/>
               </marker>
          </defs>
          <rect width="100%" height="100%" fill="#ff000f"/>
          <line x1="194.791015625" y1="225.78622436523438" stroke="white" stroke-width="17" x2="844.1951904296875" y2="1090.224853515625" xlink:marker-start="url(#line308-markerEnd)" xlink:marker-end="url(#line308-marker)" style="marker-end: url(&quot;#line308-marker&quot;); marker-start: url(&quot;#line308-markerEnd&quot;);"/>
     </svg>

Expected Image

This is rendered by Chrome. This also renders the same in FireFox, Safari, and Edge.

Sharp Code

const sharp = require('sharp')

sharp('test.svg')
    .png()
    .toFile("outfile.png", (err, info) => {
        if( err ){ console.log(`Sharp Error:\n\n ${err}`) }
        else {
            console.log(info)
        }
    });

Actual Output

The resulting image shows that the arrow head is at the wrong angle.

Environment

$ npx envinfo --binaries --system
npx: installed 1 in 1.011s

  System:
    OS: macOS Mojave 10.14.6
    CPU: (8) x64 Intel(R) Core(TM) i7-4960HQ CPU @ 2.60GHz
    Memory: 2.98 GB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.18.4 - /usr/local/bin/node
    npm: 6.14.6 - /usr/local/bin/npm

Version

$ npm ls sharp
└── sharp@0.26.3 

$ npm view sharp dist-tags.latest
0.26.3 
lovell commented 3 years ago

This is an SVG2 feature currently unsupported by librsvg - please see https://gitlab.gnome.org/GNOME/librsvg/-/issues/484

kleisauke commented 1 week ago

Issue https://gitlab.gnome.org/GNOME/librsvg/-/issues/484 is resolved now. Confirmed with the reproducer above:

Details ```console $ node -e "require('sharp')('issue-2459.svg').toFile('x.png')" ``` ![x](https://github.com/user-attachments/assets/33e1ed47-f2e7-4195-84f2-706d5b93aaf7)
lovell commented 1 week ago

@kleisauke Brilliant, thanks for checking/updating.