ropensci / rsvg

SVG renderer for R based on librsvg2
Other
95 stars 1 forks source link

Rendering bug using {rsvg} and latest librsvg #30

Open coolbutuseless opened 2 years ago

coolbutuseless commented 2 years ago

Something in the rendering has changed between librsvg v2.48.4 (macOS version from CRAN), and librsvg v2.52.8 (latest version in Brew).

The twitter logo renders correctly in the version from CRAN, but lacks the rounded rectangle corners when compiled agains latest librsvg.

Using the latest rsvg-convert on the command line still produces the correct result. It is only when using {rsvg} does it seem incorrect.

Running rsvg from CRAN works fine - the twitter logo has rounded rect corners.

library(rsvg)
#> Linking to librsvg 2.48.4

# Twitter Icon
svg_text <- "<svg xmlns=\"http://www.w3.org/2000/svg\"\naria-label=\"Twitter\" role=\"img\"\nviewBox=\"0 0 512 512\"><rect\nwidth=\"512\" height=\"512\"\nrx=\"15%\"\nfill=\"#1da1f2\"/><path fill=\"#fff\" d=\"M437 152a72 72 0 01-40 12a72 72 0 0032-40a72 72 0 01-45 17a72 72 0 00-122 65a200 200 0 01-145-74a72 72 0 0022 94a72 72 0 01-32-7a72 72 0 0056 69a72 72 0 01-32 1a72 72 0 0067 50a200 200 0 01-105 29a200 200 0 00309-179a200 200 0 0035-37\"/></svg>"

bitmap <- rsvg(charToRaw(svg_text))
im <- magick::image_read(bitmap)
grid::grid.raster(im)

Created on 2022-04-14 by the reprex package (v2.0.1)

Now compiling on my macOS machine against librsvg 2.52.8, the twitter logo rounded corners are gone.

Note that using the command line 'rsvg-convert' correctly produces the rounded corners.

library(rsvg)
#> Linking to librsvg 2.52.8

# Twitter Icon
svg_text <- "<svg xmlns=\"http://www.w3.org/2000/svg\"\naria-label=\"Twitter\" role=\"img\"\nviewBox=\"0 0 512 512\"><rect\nwidth=\"512\" height=\"512\"\nrx=\"15%\"\nfill=\"#1da1f2\"/><path fill=\"#fff\" d=\"M437 152a72 72 0 01-40 12a72 72 0 0032-40a72 72 0 01-45 17a72 72 0 00-122 65a200 200 0 01-145-74a72 72 0 0022 94a72 72 0 01-32-7a72 72 0 0056 69a72 72 0 01-32 1a72 72 0 0067 50a200 200 0 01-105 29a200 200 0 00309-179a200 200 0 0035-37\"/></svg>"

bitmap <- rsvg(charToRaw(svg_text))
im <- magick::image_read(bitmap)
grid::grid.raster(im)

Created on 2022-04-14 by the reprex package (v2.0.1)

R version 4.1.3 (2022-03-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Monterey 12.3.1
jeroen commented 2 years ago

There isn't anything we can do to control the rendering I think. You need to file this upstream for @federicomenaquintero in https://gitlab.gnome.org/GNOME/librsvg

coolbutuseless commented 2 years ago

That the SVG renders OK in the command-line and incorrectly in {rsvg} had me thinking that maybe there's been an API change between versions.

I.e. the command line rsvg-convert correctly uses some new config options, but the {rsvg} code hasn't been adapted yet.

I'm going to attempt to grok the source for rsvg-convert and I'll post back here if I see anything interesting.

coolbutuseless commented 2 years ago

Twitter Icon

svg_text <- '<svg xmlns="http://www.w3.org/2000/svg" aria-label="Twitter" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="75" fill="#1da1f2"/>'

bitmap <- rsvg(charToRaw(svg_text)) im <- magick::image_read(bitmap) grid::grid.newpage() grid::grid.raster(im)



![](https://i.imgur.com/9MfSBJk.png)

<sup>Created on 2022-04-14 by the [reprex package](https://reprex.tidyverse.org) (v2.0.1)</sup>
coolbutuseless commented 2 years ago

Found the issue!

In setup_render_handle() the viewport width/height need to be explicitly set, otherwise the "%" values on top level elements have no reference.

I'll put together a PR on a better solution, but uncommenting the viewport.width/height lines and setting a manual value works for this particular SVG

  viewport.width = 512;
  viewport.height = 512;
  rsvg_handle_render_document(svg, cr, &viewport, &err);