lottie: Take care of parentAlpha when drawing with gradient.

Change-Id: Iacdf1df1010a8afe69d15dffa5793791aabc4fef
This commit is contained in:
subhransu mohanty 2018-11-09 10:16:24 +09:00
parent 83b433d4e4
commit a30e5fe28e
4 changed files with 22 additions and 7 deletions

View File

@ -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);

View File

@ -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;

View File

@ -15,17 +15,16 @@ public:
typedef std::unordered_multimap<uint64_t, std::shared_ptr<const CacheInfo>>
VGradientColorTableHash;
bool generateGradientColorTable(const VGradientStops &stops,
bool generateGradientColorTable(const VGradientStops &stops, float alpha,
uint32_t *colorTable, int size);
inline const std::shared_ptr<const CacheInfo> getBuffer(
const VGradient &gradient)
{
uint64_t hash_val = 0;
std::shared_ptr<const CacheInfo> 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<CacheInfo>(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);

View File

@ -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;