tl;dr has anyone tried to use libcss to add CSS support to libsvgtiny? I have a small project that renders GTK icons using libsvgtiny. Its main missing feature is that it can't handle GTK's "symbolic" SVGs, which are basically just regular SVGs wrapped in an include with a <style> element at the top. The styles themselves are trivial, consisting of only a few !important color changes.
That got me wondering about CSS support in libsvgtiny. I could probably hack in special cases for the exact <style> elements I need (they're hard-coded in GTK), but it would be a lot more elegant -- and fix a bunch of existing rendering bugs -- if CSS were supported properly. To that end, I wrote a very ugly proof-of-concept that handles the SVG fill-opacity and stroke-opacity properties: 1. First, I chose to implement the fill-opacity and stroke-opacity properties because they're easy. They have the same form as the usual CSS "opacity" property. To implement them, I basically git grep'd for "opacity" in libcss and copy/pasted everything to fill-opacity and stroke-opacity. It was tedious, but otherwise not difficult because opacity is easy to parse. Handling the more complicated properties or factoring out the shared implementations of opacity, fill-opacity, and stroke-opacity would likely require someone who knows libcss better. I dumped the new properties into the default level, but this raises a question: should libcss use a different CSS level for SVG? 2. In libsvgtiny, I added a libcss context to the parser state, and then taught the SVG parser to parse a <style> element into a sheet, and append the sheet to said context. This part is just boilerplate. The build system needs to be updated to build/link against libcss. 3. I copied the css_select_handler and css_unit_ctx from netsurf into svgtiny.c. Thankfully, I didn't have to think about the unit conversions at all because opacity is a float. The select handler callbacks were tedious, but most of them can be copied from netsurf with minimal changes, fudging interned string names and replacing html-only function calls. I wound up copying the user data handler too. Who knows if any of this stuff works, but it hasn't crashed. Ultimately, since netsurf uses libsvgtiny, copy-pasting the select handler wouldn't be a great solution. I think it would make sense to factor out the libdom/libcss integration into something like a libdom-css that provides a generic css_select_handler implementation. 4. I added fill_opacity and stroke_opacity members to the SVG parser context. 5. I taught svgtiny_parse_paint_attributes() how to find the computed fill- and stroke-opacities. We're already parsing the inline style so that part is pretty easy. Once we have them, they can be set in the context. Disclaimer: I skipped composition with the parent style to save time, but that could probably be copied from netsurf too. There's a problem here: the SVG parser makes one pass through the file, using a big struct to keep track of the current color, stroke width, et cetera, as we create and append shapes to the resulting abstract representation. If a <style> element appears at the end of the SVG, its rules won't affect the shapes created earlier. (This isn't a huge problem, it's just worth noting that I half-assed this part to get the thing working.) 6. You can now render each shape with the fill_opacity and stroke_opacity from the context. Now I can say I wasn't lying when I thought "I could probably do that." Of course I skipped over the boring/hard parts, but when all is said and done, the framework can be put in place without too much extra code. Has anyone tried this before? Does it make sense for libsvgtiny? _______________________________________________ netsurf-dev mailing list -- netsurf-dev@netsurf-browser.org To unsubscribe send an email to netsurf-dev-le...@netsurf-browser.org