linebender / resvg

An SVG rendering library.
Apache License 2.0
2.85k stars 228 forks source link

usvg writing trips over defs referencing other defs #699

Closed flxzt closed 9 months ago

flxzt commented 10 months ago

When writing an usvg tree to string with the following Svg content, it seems to be failing this debug assertion while writing the group that is located in <defs>.

Reproducing the issue can be done by executing the usvg cli (built with the dev profile):

usvg minimal.svg out.svg

with this file (it is generated through cairo's svg surface in my application Rnote):

minimal

its content:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="793.701px" height="1122.52px" viewBox="0 0 793.701 1122.52">
    <defs>
        <clipPath id="clip-0">
            <path clip-rule="nonzero" d="M 0 0 L 793.699219 0 L 793.699219 1122.519531 L 0 1122.519531 Z M 0 0 " />
        </clipPath>
        <clipPath id="clip-1">
            <rect x="0" y="0" width="37" height="37" />
        </clipPath>
        <g id="source-20076" clip-path="url(#clip-1)">
            <path fill-rule="nonzero" fill="rgb(70.196078%, 77.647059%, 81.568627%)" fill-opacity="1" d="M 0.488281 0 L 0.980469 0 C 1.25 0 1.46875 0.21875 1.46875 0.488281 L 1.46875 0.980469 C 1.46875 1.25 1.25 1.46875 0.980469 1.46875 L 0.488281 1.46875 C 0.21875 1.46875 0 1.25 0 0.980469 L 0 0.488281 C 0 0.21875 0.21875 0 0.488281 0 Z M 0.488281 0 " />
        </g>
        <pattern id="pattern-0" patternUnits="userSpaceOnUse" x="0" y="0" width="37" height="37" viewBox="0 0 37 37" patternTransform="matrix(1.021486, 0, 0, 1.021486, 0, 0)">
            <use xlink:href="#source-20076" />
        </pattern>
    </defs>
    <g clip-path="url(#clip-0)">
        <path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 0 0 L 793.699219 0 L 793.699219 1122.519531 L 0 1122.519531 Z M 0 0 " />
        <path fill-rule="nonzero" fill="url(#pattern-0)" d="M 0 0 L 793.699219 0 L 793.699219 1122.519531 L 0 1122.519531 Z M 0 0 " />
    </g>
    <path fill="none" stroke-width="2" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(10.196078%, 37.254902%, 70.196078%)" stroke-opacity="1" stroke-miterlimit="10" d="M 299 165 L 478 301 " />
</svg>

the stacktrace:

thread 'main' panicked at crates/usvg/src/writer.rs:148:9:
assertion failed: self.id_map.contains_key(&key)
stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: core::panicking::panic
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:127:5
   3: usvg::writer::WriterContext::get_defs_id
             at ./crates/usvg/src/writer.rs:148:9
   4: usvg::writer::write_group_element
             at ./crates/usvg/src/writer.rs:1005:27
   5: usvg::writer::write_element
             at ./crates/usvg/src/writer.rs:834:13
   6: usvg::writer::write_elements
             at ./crates/usvg/src/writer.rs:800:9
   7: usvg::writer::write_group_element
             at ./crates/usvg/src/writer.rs:1062:5
   8: usvg::writer::write_element
             at ./crates/usvg/src/writer.rs:834:13
   9: usvg::writer::write_elements
             at ./crates/usvg/src/writer.rs:800:9
  10: usvg::writer::write_defs
             at ./crates/usvg/src/writer.rs:696:13
  11: usvg::writer::convert
             at ./crates/usvg/src/writer.rs:207:5
  12: <usvg_tree::Tree as usvg::TreeWriting>::to_string
             at ./crates/usvg/src/lib.rs:72:9
  13: usvg::process
             at ./crates/usvg/src/main.rs:447:13
  14: usvg::main
             at ./crates/usvg/src/main.rs:314:21
  15: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
LaurenzV commented 10 months ago

Yeah, it's somewhat of a known bug (see second example here), the problem is that we are currently not handling def's referencing other def's correctly.

RazrFalcon commented 10 months ago

Yes, this is a know issue. usvg CLI is beta quality. It's more like a demo at this point.

RazrFalcon commented 9 months ago

@LaurenzV if you have more tests for this issue - feel free to add them.

LaurenzV commented 9 months ago

I don't have any other ones currently, but will do if I encounter them.