From a30e5fe28ec7acd66bb08249e6f8a35c5f3494f8 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Fri, 9 Nov 2018 10:16:24 +0900 Subject: [PATCH] lottie: Take care of parentAlpha when drawing with gradient. Change-Id: Iacdf1df1010a8afe69d15dffa5793791aabc4fef --- src/lottie/lottieitem.cpp | 2 ++ src/vector/vbrush.h | 3 +++ src/vector/vdrawhelper.cpp | 15 ++++++++------- src/vector/vglobal.h | 9 +++++++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 0249bec..cb7a2ad 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -851,6 +851,7 @@ void LOTGFillItem::updateContent(int frameNo) void LOTGFillItem::updateRenderNode() { + mGradient->setAlpha(parentAlpha()); mDrawable->setBrush(VBrush(mGradient.get())); mDrawable->setFillRule(mFillRule); } @@ -926,6 +927,7 @@ void LOTGStrokeItem::updateContent(int frameNo) void LOTGStrokeItem::updateRenderNode() { float scale = getScale(mGradient->mMatrix); + mGradient->setAlpha(parentAlpha()); mDrawable->setBrush(VBrush(mGradient.get())); mDrawable->setStrokeInfo(mCap, mJoin, mMiterLimit, mWidth * scale); diff --git a/src/vector/vbrush.h b/src/vector/vbrush.h index ca03a1d..9a31715 100644 --- a/src/vector/vbrush.h +++ b/src/vector/vbrush.h @@ -17,6 +17,8 @@ public: enum class Type { Linear, Radial }; VGradient(VGradient::Type type); void setStops(const VGradientStops &stops); + void setAlpha(float alpha) {mAlpha = alpha;} + float alpha() const {return mAlpha;} VGradient() = default; public: @@ -25,6 +27,7 @@ public: VGradient::Spread mSpread; VGradient::Mode mMode; VGradientStops mStops; + float mAlpha{1.0}; union { struct { float x1, y1, x2, y2; diff --git a/src/vector/vdrawhelper.cpp b/src/vector/vdrawhelper.cpp index 90f20eb..2deb2aa 100644 --- a/src/vector/vdrawhelper.cpp +++ b/src/vector/vdrawhelper.cpp @@ -15,17 +15,16 @@ public: typedef std::unordered_multimap> VGradientColorTableHash; - bool generateGradientColorTable(const VGradientStops &stops, + bool generateGradientColorTable(const VGradientStops &stops, float alpha, uint32_t *colorTable, int size); inline const std::shared_ptr getBuffer( const VGradient &gradient) { uint64_t hash_val = 0; std::shared_ptr info; - const VGradientStops &stops = gradient.mStops; for (uint i = 0; i < stops.size() && i <= 2; i++) - hash_val += stops[i].second.premulARGB(); + hash_val += (stops[i].second.premulARGB() * gradient.alpha()); cacheAccess.lock(); @@ -72,7 +71,7 @@ protected: } auto cache_entry = std::make_shared(gradient.mStops); cache_entry->alpha = generateGradientColorTable( - gradient.mStops, cache_entry->buffer32, VGradient::colorTableSize); + gradient.mStops, gradient.alpha(), cache_entry->buffer32, VGradient::colorTableSize); cache.insert(std::make_pair(hash_val, cache_entry)); return cache_entry; } @@ -81,7 +80,7 @@ protected: std::mutex cacheAccess; }; -bool VGradientCache::generateGradientColorTable(const VGradientStops &stops, +bool VGradientCache::generateGradientColorTable(const VGradientStops &stops, float opacity, uint32_t *colorTable, int size) { int dist, idist, pos = 0, i; @@ -91,10 +90,12 @@ bool VGradientCache::generateGradientColorTable(const VGradientStops &stops, uint32_t curColor, nextColor; float delta, t, incr, fpos; + if (!vCompare(opacity, 1.0f)) alpha = true; + start = stops.data(); curr = start; if (!curr->second.isOpaque()) alpha = true; - curColor = curr->second.premulARGB(); + curColor = curr->second.premulARGB(opacity); incr = 1.0 / (float)size; fpos = 1.5 * incr; @@ -111,7 +112,7 @@ bool VGradientCache::generateGradientColorTable(const VGradientStops &stops, next = (start + i + 1); delta = 1 / (next->first - curr->first); if (!next->second.isOpaque()) alpha = true; - nextColor = next->second.premulARGB(); + nextColor = next->second.premulARGB(opacity); while (fpos < next->first && pos < size) { t = (fpos - curr->first) * delta; dist = (int)(255 * t); diff --git a/src/vector/vglobal.h b/src/vector/vglobal.h index d9cd17c..87438cf 100644 --- a/src/vector/vglobal.h +++ b/src/vector/vglobal.h @@ -259,6 +259,15 @@ public: return uint((a << 24) | (pr << 16) | (pg << 8) | (pb)); } + uint premulARGB(float opacity) const + { + int alpha = a * opacity; + int pr = (r * alpha) / 255; + int pg = (g * alpha) / 255; + int pb = (b * alpha) / 255; + return uint((alpha << 24) | (pr << 16) | (pg << 8) | (pb)); + } + public: uchar a; uchar r; -- 2.7.4