From 49f3395631e5c94f600fcee1d94dbafe692cbee6 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 6 Aug 2024 21:03:16 +0900 Subject: [PATCH] renderer: newly support the Lighten/Darken Masking options Lighten is applied, where multiple masks intersect, the highest transparency value is used. Darken is applied, where multiple masks intersect, the lowest transparency value is used. Experimental API: - CompositeMethod::LightenMask - CompositeMethod::DarkenMask issue: https://github.com/thorvg/thorvg/issues/2608 --- inc/thorvg.h | 4 +++- src/loaders/lottie/tvgLottieParser.cpp | 10 ++-------- src/renderer/sw_engine/tvgSwRaster.cpp | 17 +++++++++++++++-- src/renderer/tvgRender.h | 4 ++++ 4 files changed, 24 insertions(+), 11 deletions(-) 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: