jwmcglynn / donner

Donner SVG, a modern C++20 SVG rendering library supporting the latest SVG2 and CSS3 standards
https://jwmcglynn.github.io/donner/
ISC License
13 stars 1 forks source link

`<filter>` support #151

Open jwmcglynn opened 6 months ago

jwmcglynn commented 6 months ago

Implement filter support, based on the spec here: https://www.w3.org/TR/filter-effects/

Stage 1: MVP

This should be validated by rendering the donner splash logo

Stage 2: Full implementation

jwmcglynn commented 5 months ago

Missing features:

Filter effect chains

So the CSS property needs to contain a vector of FilterEffect variants, and each FilterEffect could potentially be a ref which resolves to a vector of FilterEffects. During resolution the refs will need to be resolved before we reach the renderer.

To represent this:

Filter effects can also contain multiple trees, as shown by Example 4 here:

<filter id="filter">
  <-- The first filter primitive tree. Ignored for filter process. -->
  <feColorMatrix type="hueRotate" values="45"/>
  <feOffset dx="10" dy="10"/>
  <feGaussianBlur stdDeviation="3"/>
  <-- The primary filter primitive tree. -->
  <feFlood flood-color="green" result="flood"/>
  <feComposite operator="in" in="SourceAlpha" in2="flood"/>
</filter>

In this case <feFlood> takes no inputs, so it discards the prior part of the tree. The final FilterEffect chain for this should only contain [feFlood, feComposite].

Length properties

For SVG DOM elements, there are no units:

  <feGaussianBlur stdDeviation="3"/>

However for the filter presentation attributes, there are:

filter: blur(5in)

These need to be resolved before rendering.

Bounding boxes

Filter effects have bounded boxes both from the <filter> property, and on filter primitives. These need to be considered during the filtering process.