linebender / resvg

An SVG rendering library.
Mozilla Public License 2.0
2.79k stars 225 forks source link

Transforms ignored after filters #381

Closed afdw closed 8 months ago

afdw commented 3 years ago

Consider the following file:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512" viewBox="0 0 512 512">
    <defs>
        <filter id="filter-remove-color-and-invert-alpha" x="0%" y="0%" width="100%" height="100%">
            <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 -1 1"/>
        </filter>
        <filter id="filter-0" x="0%" y="0%" width="100%" height="100%">
            <feImage xlink:href="#compositing-group-1" result="source" x="0" y="0" width="737.28" height="737.28"/>
            <feImage xlink:href="#compositing-group-2" result="destination" x="0" y="0" width="737.28" height="737.28"/>
            <feComposite in="source" in2="destination" operator="xor" color-interpolation-filters="sRGB"/>
        </filter>
        <filter id="filter-1" x="0%" y="0%" width="100%" height="100%">
            <feImage xlink:href="#compositing-group-3" result="source" x="0" y="0" width="737.28" height="737.28"/>
            <feImage xlink:href="#compositing-group-4" result="destination" x="0" y="0" width="737.28" height="737.28"/>
            <feComposite in="source" in2="destination" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" color-interpolation-filters="sRGB"/>
        </filter>
        <g id="compositing-group-0" transform="translate(142.64, 142.64)">
            <rect x="-142.64" y="-142.64" width="737.28" height="737.28" fill-opacity="0"/>
            <rect x="-142.64" y="-142.64" width="737.28" height="737.28" fill="rgb(100%, 100%, 100%)"/>
        </g>
        <mask id="mask-0">
            <use xlink:href="#compositing-group-0"/>
        </mask>
        <mask id="mask-1">
            <use xlink:href="#compositing-group-0" filter="url(#filter-remove-color-and-invert-alpha)"/>
        </mask>
        <mask id="mask-2">
            <g transform="translate(142.64, 142.64)">
                <path fill="rgb(100%, 100%, 100%)" d="M 10 0 L 130 0 L 130 90 L 10 90 Z M 10 0 "/>
            </g>
        </mask>
        <g id="compositing-group-1" mask="url(#mask-2)">
            <g transform="translate(142.64, 142.64)">
                <rect x="-142.64" y="-142.64" width="737.28" height="737.28" fill="rgb(0%, 0%, 90%)" fill-opacity="0.4"/>
            </g>
        </g>
        <g id="compositing-group-2" transform="translate(142.64, 142.64)">
            <path fill="rgb(70%, 0%, 0%)" fill-opacity="0.8" d="M -30 -30 L 90 -30 L 90 60 L -30 60 Z M -30 -30 "/>
        </g>
        <g id="compositing-group-3" filter="url(#filter-0)" mask="url(#mask-0)">
            <rect x="0" y="0" width="737.28" height="737.28"/>
        </g>
        <g id="compositing-group-4" mask="url(#mask-1)">
            <use xlink:href="#compositing-group-2"/>
        </g>
        <g id="source-5">
            <g filter="url(#filter-1)" transform="translate(-142.64, -142.64)">
                <rect x="0" y="0" width="737.28" height="737.28"/>
            </g>
        </g>
    </defs>
    <use xlink:href="#source-5" transform="matrix(1, 0, 0, 1, 30, 30)"/>
</svg>
The results are: resvg rsvg, Chrome
re r

The problem is that the transform="translate(-142.64, -142.64)" and transform="matrix(1, 0, 0, 1, 30, 30)" parts are ignored for some reason.

This might be related to #254, but these are just translations, nothing more complex.

RazrFalcon commented 3 years ago

Will have to investigate this one.

This might be related to #254, but these are just translations, nothing more complex.

No. That issue is all about compositing, not placement.

RazrFalcon commented 3 years ago

Your image is broken in Firefox, Safari and Inkscape. Just saying.

afdw commented 3 years ago

Your image is broken in Firefox.

This is because of SVG filters feImage with xlink:href doesn't work with fragments.

Your image is broken in Safari.

I do not have Safari to test (I think the macOS and preferable even Apple hardware are needed for that).

Your image is broken in Inkscape.

I know, but I did figure out why yet. Some other similar images work there.

Just saying.

Do you have any hints on how to make it easier for renderers?

RazrFalcon commented 3 years ago

feImage is an absolute minefield and I have no idea what's wrong with this particular image. It would take a while to figure out. At the first glance looks like transform propagation is broken, but I have no idea how to fix it.

Do you have any hints on how to make it easier for renderers?

I still have no idea what is happening.

LaurenzV commented 8 months ago

This has been fixed by https://github.com/RazrFalcon/resvg/commit/e018daed569df9619f486b81fd2362652feceadf

The image now matches the output from Chrome.

image

test