adobe / svg-native-viewer

SVG Native viewer is a library that parses and renders SVG Native documents
Apache License 2.0
155 stars 37 forks source link

Color mix support #193

Open dirkschulze opened 11 months ago

dirkschulze commented 11 months ago

Add support for CSS function color-mix()

Description

This allows blending 2 colors with each other:

color-mix(in srgb, black, white 80%)
color-mix(in srgb, black 80%, white)
color-mix(in srgb, rgb(255, 127, 0) 80%, rgb(0, 127, 0))

For now, only srgb is supported (we do not support other color functions/spaces anyway).

Related Issue

None

Motivation and Context

Main motivation are gradients and emulated color stops: SVG gradients do not support mid-points. So those have to be emulated. The issue is when we use custom properties for the colors. The emulated color stops currently need to be of actual colours. However, we rather want the color stops to "get computed" on the fly.

Here an example of the purpose:

<linearGradient id="linear-gradient" x1="0" y1="112" x2="173" y2="112" gradientUnits="userSpaceOnUse">
  <stop offset="0" stop-color="var(--MyPink, #ff13ff)"/>
  <stop offset=".0289422631" stop-color="#da22db"/>
  <stop offset=".0737269045" stop-color="#a738aa"/>
  <stop offset=".1206977917" stop-color="#7a4b7e"/>
  <stop offset=".1689188574" stop-color="#545b5a"/>
  <stop offset=".2187327679" stop-color="#35683c"/>
  <stop offset=".2706767167" stop-color="#1e7225"/>
  <stop offset=".3256464648" stop-color="#0d7914"/>
  <stop offset=".3857221444" stop-color="#037d0b"/>
  <stop offset=".4604860239" stop-color="var(--MyGreen, #007f08)"/>
  <stop offset=".5149043522" stop-color="#00810d"/>
  <stop offset=".5830077108" stop-color="#03871c"/>
  <stop offset=".6584280728" stop-color="#079136"/>
  <stop offset=".7391209026" stop-color="#0da05a"/>
  <stop offset=".8240713671" stop-color="#15b387"/>
  <stop offset=".9120222892" stop-color="#1fcabf"/>
  <stop offset="1" stop-color="var(--MyBlue, #2ae4ff)"/>
</linearGradient>
<linearGradient id="linear-gradient2" x1="0" y1="112" x2="173" y2="112" gradientUnits="userSpaceOnUse">
  <stop offset="0" stop-color="var(--MyPink, #ff13ff)"/>
  <stop offset=".0289422631" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 6.285155596011130%)"/>
  <stop offset=".0737269045" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 16.01067148044664%)"/>
  <stop offset=".1206977917" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 26.21095656232358%)"/>
  <stop offset=".1689188574" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 36.68273272864471%)"/>
  <stop offset=".2187327679" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 47.50041402939526%)"/>
  <stop offset=".2706767167" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 58.78065840251878%)"/>
  <stop offset=".3256464648" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 70.71799097006210%)"/>
  <stop offset=".3857221444" stop-color="color-mix(in srgb, var(--MyPink, #ff13ff), var(--MyGreen, #007f08) 83.76413710305443%)"/>
  <stop offset=".4604860239" stop-color="var(--MyGreen, #007f08)"/>
  <stop offset=".5149043522" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 14.28571428571428%)"/>
  <stop offset=".5830077108" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 28.57142857142857%)"/>
  <stop offset=".6584280728" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 42.85714285714287%)"/>
  <stop offset=".7391209026" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 57.14285714285716%)"/>
  <stop offset=".8240713671" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 71.42857142857145%)"/>
  <stop offset=".9120222892" stop-color="color-mix(in srgb, var(--MyGreen, #ff13ff), var(--MyBlue, #007f08) 85.71428571428574%)"/>
  <stop offset="1" stop-color="var(--MyBlue, #2ae4ff)"/>
</linearGradient>

(Warning: The above gradients are actually not the same. Only meant for demonstration purposes.)

How Has This Been Tested?

Via unit testing: Added googletest as actual unit testing system to CircleCI.

Screenshots (if appropriate):

Types of changes

Checklist: