|
14 | 14 | import androidx.annotation.CallSuper;
|
15 | 15 | import androidx.annotation.FloatRange;
|
16 | 16 | import androidx.annotation.Nullable;
|
| 17 | +import androidx.core.graphics.PaintCompat; |
17 | 18 |
|
18 | 19 | import com.airbnb.lottie.L;
|
19 | 20 | import com.airbnb.lottie.LottieComposition;
|
@@ -117,6 +118,8 @@ static BaseLayer forModel(
|
117 | 118 | float blurMaskFilterRadius = 0f;
|
118 | 119 | @Nullable BlurMaskFilter blurMaskFilter;
|
119 | 120 |
|
| 121 | + @Nullable LPaint solidWhitePaint; |
| 122 | + |
120 | 123 | BaseLayer(LottieDrawable lottieDrawable, Layer layerModel) {
|
121 | 124 | this.lottieDrawable = lottieDrawable;
|
122 | 125 | this.layerModel = layerModel;
|
@@ -258,7 +261,7 @@ public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {
|
258 | 261 | }
|
259 | 262 | }
|
260 | 263 | int alpha = (int) ((parentAlpha / 255f * (float) opacity / 100f) * 255);
|
261 |
| - if (!hasMatteOnThisLayer() && !hasMasksOnThisLayer()) { |
| 264 | + if (!hasMatteOnThisLayer() && !hasMasksOnThisLayer() && getBlendMode() == LBlendMode.NORMAL) { |
262 | 265 | matrix.preConcat(transform.getMatrix());
|
263 | 266 | if (L.isTraceEnabled()) {
|
264 | 267 | L.beginSection("Layer#drawLayer");
|
@@ -307,13 +310,31 @@ public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {
|
307 | 310 | L.beginSection("Layer#saveLayer");
|
308 | 311 | }
|
309 | 312 | contentPaint.setAlpha(255);
|
| 313 | + PaintCompat.setBlendMode(contentPaint, getBlendMode().toNativeBlendMode()); |
310 | 314 | Utils.saveLayerCompat(canvas, rect, contentPaint);
|
311 | 315 | if (L.isTraceEnabled()) {
|
312 | 316 | L.endSection("Layer#saveLayer");
|
313 | 317 | }
|
314 | 318 |
|
315 | 319 | // Clear the off screen buffer. This is necessary for some phones.
|
316 |
| - clearCanvas(canvas); |
| 320 | + if (getBlendMode() != LBlendMode.MULTIPLY) { |
| 321 | + clearCanvas(canvas); |
| 322 | + } else { |
| 323 | + // Due to the difference between PorterDuffMode.MULTIPLY (which we use for compatibility |
| 324 | + // with Android < Q) and BlendMode.MULTIPLY (which is the correct, alpha-blended mode), |
| 325 | + // we will alpha-blend the contents of this layer on top of a white background before |
| 326 | + // we multiply it with the opaque substrate below (with canvas.restore()). |
| 327 | + // |
| 328 | + // Since white is the identity color for multiplication, this will behave as if we |
| 329 | + // had correctly performed an alpha-blended multiply (such as BlendMode.MULTIPLY), but |
| 330 | + // will work pre-Q as well. |
| 331 | + if (solidWhitePaint == null) { |
| 332 | + solidWhitePaint = new LPaint(); |
| 333 | + solidWhitePaint.setColor(0xffffffff); |
| 334 | + } |
| 335 | + canvas.drawRect(rect.left - 1, rect.top - 1, rect.right + 1, rect.bottom + 1, solidWhitePaint); |
| 336 | + } |
| 337 | + |
317 | 338 | if (L.isTraceEnabled()) {
|
318 | 339 | L.beginSection("Layer#drawLayer");
|
319 | 340 | }
|
|
0 commit comments