Skip to content

WIP: Port some filter architecture and the offset filter effect to Rust

Ivan Molodetskikh requested to merge YaLTeR/librsvg:filters-to-rust into master

Current state of the work:

  • _RsvgFilterContext was moved to Rust completely and became filter_context.rs:FilterContext. Every access from the C code was replaced with accessor functions;
  • rsvg_filter_render() was ported to Rust and is located in filters/ffi.rs, including a one-line fix for #218 (closed);
  • some basic Rust filter infrastructure was established in filters/mod.rs, including the Filter trait for filter effects;
  • the offset filter effect was ported to Rust, you can find it in filters/offset.rs. I also added a test for the offset filter, generated with the C code, the colors are slightly wrong compared to the reference image.

The current direction I want to take:

  • change Filter::render() to return Result<FilterResult, Error> instead of making filters ignore errors and store the result themselves. This is more Rust-ic and will allow to potentially handle errors like surfaces not being created in the future;
  • make the output of PrimitiveWithInput::get_input() an opaque type with pixel iteration methods. Pixel iteration was the original idea, and not pinning ourselves to cairo::ImageSurface will allow implementing the FillPaint and StrokePaint things that are tiled infinitely as far as I could tell;
  • port Primitive::get_bounds() to Rust (maybe move somewhere else like FilterContext). This will get rid of the remaining ugly call to rsvg_filter_primitive_get_bounds() from a couple of places.

The issues:

  • cairo::ImageSurface doesn't have to_glib_full() implemented, leading to the hack in the end of filters/ffi.rs;
  • cairo::ImageSurface doesn't have read-only pixel data borrows, leading to the hack in filters/offset.rs;
  • for some reason porting the infrastructure to Rust made the composite filter effect produce a slightly different image on the test. A couple of edge pixels and lines are different, see the attachment. Other two filters (component transfer and offset) give the same outputs as the C version.

filters-composite-02-b-diff

Edited by Ivan Molodetskikh

Merge request reports