From b20d5da552fcfad94215dd46f45331b9440c729c 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 ba2313b8..9bd11c69 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -165,7 +165,9 @@ enum class CompositeMethod 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 6edf9661..c8a7aa33 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 a64ca830..19b60970 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 c4b0efcc..0a64f050 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -323,6 +323,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); @@ -356,6 +358,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: