Maven Central Last Commit License Scala Version Scala Native Version
librsvg provides Scala Native bindings for librsvg, the GNOME SVG rendering library. It renders SVG documents directly into a Cairo context, so a scalable vector graphic composites into a larger Cairo scene with full clip, transform and opacity support — no intermediate raster step.
librsvg's internals were rewritten in Rust, but the library still ships a stable C API/ABI
(librsvg-2), so it binds like any other C library. This project pairs it with
libcairo: you load an SVG into a Handle, then render it onto
a libcairo Context.
The programmer-friendly facade lives in the io.github.edadma.librsvg package — that is the only
package you need to import. The io.github.edadma.librsvg.extern package holds the raw C interop
using Scala Native's unsafe types; nothing in the public facade exposes those types, so you never
deal with manual memory management or pointer conversions.
This library is published for Scala Native to Maven Central. The librsvg C library (and Cairo) must be installed on your system:
brew install librsvg # macOS (Homebrew) — pulls in cairo + glib sudo apt install librsvg2-dev # Debian / Ubuntu
Enable Scala Native in project/plugins.sbt:
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.12")
Add the dependency in build.sbt (it brings libcairo transitively):
libraryDependencies += "io.github.edadma" %%% "librsvg" % "0.0.4"
Then import the facade:
import io.github.edadma.librsvg._ import io.github.edadma.libcairo._
Load an SVG from a string, render it into a Cairo image surface, and write a PNG:
import io.github.edadma.librsvg._ import io.github.edadma.libcairo._ @main def run(): Unit = val svg = """<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"> | <rect x="4" y="4" width="56" height="56" rx="12" fill="#4dabf7"/> | <circle cx="32" cy="32" r="16" fill="#ffffff"/> | <path d="M24 32 l6 6 l12 -14" stroke="#4dabf7" stroke-width="4" fill="none" | stroke-linecap="round" stroke-linejoin="round"/> |</svg>""".stripMargin val handle = handleNewFromString(svg) handle.intrinsicSize.foreach { case (w, h) => println(s"intrinsic size: ${w}x$h") } val surface = imageSurfaceCreate(Format.ARGB32, 64, 64) val cr = surface.create handle.renderDocument(cr, 0, 0, 64, 64) // draws into the 64x64 viewport surface.writeToPNG("rsvg-demo.png") cr.destroy() surface.destroy() handle.destroy()
Loading (each throws RsvgException on a parse error):
handleNewFromFile(filename: String): HandlehandleNewFromData(data: Array[Byte]): Handle— plain.svgor gzip-compressed.svgzhandleNewFromString(svg: String): Handle
On a Handle:
renderDocument(cr: Context, x, y, width, height): Boolean— render into a viewport rectangle on a libcairoContextintrinsicSize: Option[(Double, Double)]— the document's pixel size when it declares onesetDpi(dpi: Double): Unit— resolution for physical units (pt,cm, ...)destroy(): Unit— release the handle
API documentation is forthcoming; documentation for the C library is found here.