@@ -1292,6 +1292,9 @@ void WS2812FX::service() {
12921292}
12931293
12941294// https://en.wikipedia.org/wiki/Blend_modes but using a for top layer & b for bottom layer
1295+ static uint8_t _top (uint8_t a, uint8_t b) { return a; } // function currently unused
1296+ static uint8_t _bottom (uint8_t a, uint8_t b) { return b; } // function currently unused
1297+ static uint8_t _add (uint8_t a, uint8_t b) { unsigned t = a + b; return t > 255 ? 255 : t; } // function currently unused
12951298static uint8_t _subtract (uint8_t a, uint8_t b) { return b > a ? (b - a) : 0 ; }
12961299static uint8_t _difference (uint8_t a, uint8_t b) { return b > a ? (b - a) : (a - b); }
12971300static uint8_t _average (uint8_t a, uint8_t b) { return (a + b) >> 1 ; }
@@ -1314,29 +1317,31 @@ static uint8_t _softlight (uint8_t a, uint8_t b) { return (b * b * (255 - 2 * a)
13141317static uint8_t _dodge (uint8_t a, uint8_t b) { return _divide (~a,b); }
13151318static uint8_t _burn (uint8_t a, uint8_t b) { return ~_divide (a,~b); }
13161319
1320+ #define APPLY_BLEND (op ) c.r = op(tC.r, bC.r); c.g = op(tC.g, bC.g); c.b = op(tC.b, bC.b); c.w = op(tC.w, bC.w)
1321+
13171322static uint32_t segblend (CRGBW tcol, CRGBW bcol, CRGBW bgcol, uint8_t blendMode) {
13181323 CRGBW tC (tcol); CRGBW bC (bcol); CRGBW c; // note: using aliases shrinks code size for some weird compiler reasons, no speed difference in tests
13191324 // note2: using CRGBW instead of uint32_t improves speed as well as code size
13201325 switch (blendMode) {
13211326 case 0 : return tcol.color32 ; // Top
13221327 case 1 : return bcol.color32 ; // Bottom
13231328 case 2 : return color_add (tcol, bcol, false ); // Add
1324- case 3 : c.r = _subtract (tC.r , bC.r ); c.g = _subtract (tC.g , bC.g ); c.b = _subtract (tC.b , bC.b ); c.w = _subtract (tC.w , bC.w ); break ; // Subtract
1325- case 4 : c.r = _difference (tC.r , bC.r ); c.g = _difference (tC.g , bC.g ); c.b = _difference (tC.b , bC.b ); c.w = _difference (tC.w , bC.w ); break ; // Difference
1326- case 5 : c.r = _average (tC.r , bC.r ); c.g = _average (tC.g , bC.g ); c.b = _average (tC.b , bC.b ); c.w = _average (tC.w , bC.w ); break ; // Average
1327- case 6 : c.r = _multiply (tC.r , bC.r ); c.g = _multiply (tC.g , bC.g ); c.b = _multiply (tC.b , bC.b ); c.w = _multiply (tC.w , bC.w ); break ; // Multiply
1328- case 7 : c.r = _divide (tC.r , bC.r ); c.g = _divide (tC.g , bC.g ); c.b = _divide (tC.b , bC.b ); c.w = _divide (tC.w , bC.w ); break ; // Divide
1329- case 8 : c.r = _lighten (tC.r , bC.r ); c.g = _lighten (tC.g , bC.g ); c.b = _lighten (tC.b , bC.b ); c.w = _lighten (tC.w , bC.w ); break ; // Lighten
1330- case 9 : c.r = _darken (tC.r , bC.r ); c.g = _darken (tC.g , bC.g ); c.b = _darken (tC.b , bC.b ); c.w = _darken (tC.w , bC.w ); break ; // Darken
1331- case 10 : c.r = _screen (tC.r , bC.r ); c.g = _screen (tC.g , bC.g ); c.b = _screen (tC.b , bC.b ); c.w = _screen (tC.w , bC.w ); break ; // Screen
1332- case 11 : c.r = _overlay (tC.r , bC.r ); c.g = _overlay (tC.g , bC.g ); c.b = _overlay (tC.b , bC.b ); c.w = _overlay (tC.w , bC.w ); break ; // Overlay
1333- case 12 : c.r = _hardlight (tC.r , bC.r ); c.g = _hardlight (tC.g , bC.g ); c.b = _hardlight (tC.b , bC.b ); c.w = _hardlight (tC.w , bC.w ); break ; // Hardlight
1334- case 13 : c.r = _softlight (tC.r , bC.r ); c.g = _softlight (tC.g , bC.g ); c.b = _softlight (tC.b , bC.b ); c.w = _softlight (tC.w , bC.w ); break ; // Softlight
1335- case 14 : c.r = _dodge (tC.r , bC.r ); c.g = _dodge (tC.g , bC.g ); c.b = _dodge (tC.b , bC.b ); c.w = _dodge (tC.w , bC.w ); break ; // Dodge
1336- case 15 : c.r = _burn (tC.r , bC.r ); c.g = _burn (tC.g , bC.g ); c.b = _burn (tC.b , bC.b ); c.w = _burn (tC.w , bC.w ); break ; // Burn
1329+ case 3 : APPLY_BLEND (_subtract); break ; // Subtract
1330+ case 4 : APPLY_BLEND (_difference); break ; // Difference
1331+ case 5 : APPLY_BLEND (_average); break ; // Average
1332+ case 6 : APPLY_BLEND (_multiply); break ; // Multiply
1333+ case 7 : APPLY_BLEND (_divide); break ; // Divide
1334+ case 8 : APPLY_BLEND (_lighten); break ; // Lighten
1335+ case 9 : APPLY_BLEND (_darken); break ; // Darken
1336+ case 10 : APPLY_BLEND (_screen); break ; // Screen
1337+ case 11 : APPLY_BLEND (_overlay); break ; // Overlay
1338+ case 12 : APPLY_BLEND (_hardlight); break ; // Hardlight
1339+ case 13 : APPLY_BLEND (_softlight); break ; // Softlight
1340+ case 14 : APPLY_BLEND (_dodge); break ; // Dodge
1341+ case 15 : APPLY_BLEND (_burn); break ; // Burn
1342+ case 32 : return tcol.color32 == bgcol.color32 ? bcol.color32 : tcol.color32 ; // Stencil: backgroundcolor -> transparent, use top color otherwise
13371343 // note: stencil mode is a special case: it works only on full color comparison and wont work correctly on a colorchannel base
13381344 // enumerate to 32 to allow future additions above in case a function array will be used again
1339- case 32 : return tcol.color32 == bgcol.color32 ? bcol.color32 : tcol.color32 ; // Stencil: backgroundcolor -> transparent, use top color otherwise
13401345 default : return tcol.color32 ; // fallback to Top
13411346 }
13421347 return c.color32 ;
0 commit comments