We also need to generate vector PDFs serverside — so we use a node library that speaks the HTML Canvas API and can generate PDFs. This way the result is exactly the same as the rendered sheet music in the web browser. Nice!
The upshot is: this kind of library allows for code reuse in non-browser contexts.
Our graphics engine works with Canvas API instructions — like "draw a line from point (A,B) to (C,D)." This API is small enough and low-level enough that it can also generate pristine vector output.
That's in fact one of the features of Skia Canvas (vector output in PDF and SVG).
I am not sure if it would be viable to use for thousands of PDF generation per minute but it worked great. I wasted a lot of time trying to find a good lib for HTML->PDF and they all kinda sucked in different ways. The only downside is that the chrome PDF api doesn't have a way to generate a table of contents with page numbers.
Cairo?
Of course there are 2D drawing libraries on the major platforms (and CoreGraphics and Direct2D are very different, there’s also GDI+), but it was a weird question to start: what’s the use of a portable library. But furthermore, skia is not just a portability wrapper.
Skia is useful because it provides a powerful, performance oriented common target 2D drawing library, and it is more than a lowest common denominator wrapper.
It could be Qt, SDL, SFML, or anything else with similar goals.
One the one hand this is lower-level. On the other hand, I've used puppeteer as my 2D graphics library. I get Canvas 2D, and WebGL, and WebGPU, and all of HTML/CSS (so Text with effects, background images, CSS transforms, etc). I get image and video loading. I can then use the screenshot functionality to make an image of whatever I put together. It's overkill, but for my use case I don't care. It works, it's cross platform, it solves my problem.
Skia is the most modern library if you want to render shapes onto an image/surface.
According to the example `import {Window} from 'skia-canvas'` you can also use it to draw onto a spawned window on a desktop.
We had a rendering engine backed by canvas, so it was easy to just redirect it to this to get the file output. (not everything was visible on the user's screen all the time so couldn't just save from the client)