diff --git a/inc/thorvg.h b/inc/thorvg.h index ab69d62b..32145249 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -165,7 +165,9 @@ enum class CompositeMethod : uint8_t AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API) SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API) IntersectMask, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API) - DifferenceMask ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API) + DifferenceMask, ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API) + LightenMask, ///< Where multiple masks intersect, the highest transparency value is used. (Experimental API) + DarkenMask ///< Where multiple masks intersect, the lowest transparency value is used. (Experimental API) }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index f12cd5c6..525405a0 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -71,14 +71,8 @@ CompositeMethod LottieParser::getMaskMethod(bool inversed) case 's': return CompositeMethod::SubtractMask; case 'i': return CompositeMethod::IntersectMask; case 'f': return CompositeMethod::DifferenceMask; - case 'l': { - TVGLOG("LOTTIE", "Mask Lighten is not supported"); - return CompositeMethod::None; - } - case 'd': { - TVGLOG("LOTTIE", "Mask Darken is not supported"); - return CompositeMethod::None; - } + case 'l': return CompositeMethod::LightenMask; + case 'd': return CompositeMethod::DarkenMask; default: return CompositeMethod::None; } } diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index e8eaaf7a..5c82b12a 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -194,10 +194,21 @@ static inline uint8_t _opMaskDifference(uint8_t s, uint8_t d, uint8_t a) } +static inline uint8_t _opMaskLighten(uint8_t s, uint8_t d, uint8_t a) +{ + return (s > d) ? s : d; +} + + +static inline uint8_t _opMaskDarken(uint8_t s, uint8_t d, uint8_t a) +{ + return (s < d) ? s : d; +} + + static inline bool _direct(CompositeMethod method) { - //subtract & Intersect allows the direct composition - if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask) return true; + if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask || method == CompositeMethod::DarkenMask) return true; return false; } @@ -209,6 +220,8 @@ static inline SwMask _getMaskOp(CompositeMethod method) case CompositeMethod::SubtractMask: return _opMaskSubtract; case CompositeMethod::DifferenceMask: return _opMaskDifference; case CompositeMethod::IntersectMask: return _opMaskIntersect; + case CompositeMethod::LightenMask: return _opMaskLighten; + case CompositeMethod::DarkenMask: return _opMaskDarken; default: return nullptr; } } diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index a78c6595..75733fba 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -321,6 +321,8 @@ static inline bool MASK_REGION_MERGING(CompositeMethod method) //these might expand the rendering region case CompositeMethod::AddMask: case CompositeMethod::DifferenceMask: + case CompositeMethod::LightenMask: + case CompositeMethod::DarkenMask: return true; default: TVGERR("RENDERER", "Unsupported Composite Method! = %d", (int)method); @@ -354,6 +356,8 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod* renderer, Composi case CompositeMethod::DifferenceMask: case CompositeMethod::SubtractMask: case CompositeMethod::IntersectMask: + case CompositeMethod::LightenMask: + case CompositeMethod::DarkenMask: return ColorSpace::Grayscale8; //TODO: Optimize Luma/InvLuma colorspace to Grayscale8 case CompositeMethod::LumaMask: