TinyVG / specification

The specification for TinyVG. This is the central authority for the file system
https://tinyvg.tech/
MIT License
246 stars 7 forks source link

[Proposal] Allow group opacity #24

Closed ikskuh closed 2 years ago

ikskuh commented 2 years ago

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:

neinseg commented 2 years ago

Some things I notice on this:

  1. 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.

  2. 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.

  3. 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.

ikskuh commented 2 years ago

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.

ikskuh commented 2 years ago

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.