[Proposal] Allow group opacity
ikskuh opened this issue · comments
The easiest one is https://github.com/RazrFalcon/resvg-test-suite/blob/master/svg/a-opacity-001.svg This is currently impossible to implement.
This is necessary to render images like that:
Some things I notice on this:
-
Groups would increase implementation complexity and in particular memory use. AFAIK the only way to implement groups is to create a new canvas / pixel buffer, render the group's children into that and then alpha composite that pixel buffer. Right now, implementing TinyVG only requires a single canvas / pixel buffer, so an implementation of TinyVG that renders into a canvas of a maximum size known at compile time can be built to work with statically allocated memory. In particular for embedded platforms this is a great feature since those platforms do not have a lot of RAM to start with, and sometimes even lack a dynamic memory allocator. Introducing groups for alpha composition like this means using the simple approach of one canvas per group, in the worst case rendering a tinyvg file may need memory linear in the file's length. I think it is possible to render a file with only two canvases, but that requires re-ordering draw operations within groups and increases implementation complexity while still needing twice the current amount of memory.
-
The example above is in fact possible with the current TinyVG spec, just not by using three circles. Instead, the circles have to be "flattened" into three non-overlapping paths. While this is not trivial, it can be done during conversion from SVG through a polygon clipping library such as clipper (see gerbolyze's
svg-flatten
for an example). This is not a trivial operation, but can be done and putting that complexity into the file conversion step instead of increasing the renderer's memory footprint might be worthwhile. -
However, in case such a group feature would be part of the spec, it would allow for "easy" implementation of SVG-like mask and clip operations as well, which in turn would allow the concise specification of pattern fills. Right now, converting an SVG path with a pattern fill into TinyVG requires the converter to perform polygon (path) clipping, which is hard. With arbitrary alpha blending it could render the fill pattern into a group, then alpha-mask that with the path outline.
Yeah, i noticed those things as well and especially 1) makes me rather not accept the feature as we an do 2) still. The linear stream makes stuff a lot simpler and easier to handle/implement than hierachical structures with groups.
Groups of any kind are rejected as they require building a DOM/AST of the file before rendering and also require either a very complex renderer or the use of framebuffers. TinyVG was designed to not require those.