weisJ/jsvg

feMerge is not supported

Closed this issue · 6 comments

Thanks for an excellent library, it can correctly render mostly all my project icons except ones with feMerge filter.

SVG:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22" height="22" viewBox="0 0 22 22">
  <defs>
    <circle id="radio-a" cx="11" cy="11" r="8"/>
    <filter id="radio-b" width="115.6%" height="115.6%" x="-7.8%" y="-7.8%" filterUnits="objectBoundingBox">
      <feGaussianBlur in="SourceAlpha" result="shadowBlurInner1" stdDeviation="1"/>
      <feOffset in="shadowBlurInner1" result="shadowOffsetInner1"/>
      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" k2="-1" k3="1" operator="arithmetic" result="shadowInnerInner1"/>
      <feColorMatrix in="shadowInnerInner1" result="shadowMatrixInner1" values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0"/>
      <feGaussianBlur in="SourceAlpha" result="shadowBlurInner2" stdDeviation=".5"/>
      <feOffset dy="1.5" in="shadowBlurInner2" result="shadowOffsetInner2"/>
      <feComposite in="shadowOffsetInner2" in2="SourceAlpha" k2="-1" k3="1" operator="arithmetic" result="shadowInnerInner2"/>
      <feColorMatrix in="shadowInnerInner2" result="shadowMatrixInner2" values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0"/>
      <feMerge>
        <feMergeNode in="shadowMatrixInner1"/>
        <feMergeNode in="shadowMatrixInner2"/>
      </feMerge>
    </filter>
  </defs>
  <g fill="none" fill-rule="evenodd">
    <use fill="#FFF" xlink:href="#radio-a"/>
    <use fill="#000" filter="url(#radio-b)" xlink:href="#radio-a"/>
    <path fill="#000" fill-opacity=".23" d="M11,19 C6.581722,19 3,15.418278 3,11 C3,6.581722 6.581722,3 11,3 C15.418278,3 19,6.581722 19,11 C19,15.418278 15.418278,19 11,19 Z M11,18 C14.8659932,18 18,14.8659932 18,11 C18,7.13400675 14.8659932,4 11,4 C7.13400675,4 4,7.13400675 4,11 C4,14.8659932 7.13400675,18 11,18 Z"/>
  </g>
</svg>

Expected:
Screenshot 2023-03-15 at 11 31 32

Actual:
Screenshot 2023-03-15 at 11 31 56

weisJ commented

Thanks for bringing this up. It’s good to know what filter effects are being used, so I know what to work on. Note that your svg also used feOffset and feComposite both of which I’ll also have to implement for it work complete (but I’m on it). I’ll also have to look into a weird behaviour with gaussian blurs on the SourceAlpha.

weisJ commented

feMerge and feOffset are now supported. feComposite is still in progress. The gaussian blur issues have also been resolved.

Another example, where feComposite is important:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="22" viewBox="0 0 18 22">
  <defs>
    <rect id="bottomleft-b" width="20" height="21"/>
    <filter id="bottomleft-a" width="270%" height="261.9%" x="-85%" y="-61.9%" filterUnits="objectBoundingBox">
      <feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/>
      <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="5"/>
      <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
      <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.3 0"/>
    </filter>
  </defs>
  <g fill="none" fill-rule="evenodd" transform="translate(10 -13)">
    <use fill="#000" filter="url(#bottomleft-a)" xlink:href="#bottomleft-b"/>
    <use fill="#FFF" fill-opacity="0" xlink:href="#bottomleft-b"/>
  </g>
</svg>

expected:
Screenshot 2023-04-19 at 20 11 04

actual:
Screenshot 2023-04-19 at 20 10 39

weisJ commented

feComposite is now also supported

Thanks! It is better now, but still rendering is not correct:

Expected (I checked Apache Batik and CEF (chrome)): see above.

Actual:
Screenshot 2023-04-20 at 20 29 29

These SVGs are used to draw shadows:
Screenshot 2023-04-20 at 20 31 01

As you can see, JSVG produces an incorrect image (check the bottom corners).