1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkBitmap.h"
9 #include "SkColorFilter.h"
10 #include "SkPaintPriv.h"
11 #include "SkImage.h"
12 #include "SkPaint.h"
13 #include "SkShader.h"
14 
changes_alpha(const SkPaint & paint)15 static bool changes_alpha(const SkPaint& paint) {
16     SkColorFilter* cf = paint.getColorFilter();
17     return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
18 }
19 
Overwrites(const SkPaint * paint,ShaderOverrideOpacity overrideOpacity)20 bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) {
21     if (!paint) {
22         // No paint means we default to SRC_OVER, so we overwrite iff our shader-override
23         // is opaque, or we don't have one.
24         return overrideOpacity != kNotOpaque_ShaderOverrideOpacity;
25     }
26 
27     SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity;
28 
29     if (!changes_alpha(*paint)) {
30         const unsigned paintAlpha = paint->getAlpha();
31         if (0xff == paintAlpha && overrideOpacity != kNotOpaque_ShaderOverrideOpacity &&
32             (!paint->getShader() || paint->getShader()->isOpaque()))
33         {
34             opacityType = SkXfermode::kOpaque_SrcColorOpacity;
35         } else if (0 == paintAlpha) {
36             if (overrideOpacity == kNone_ShaderOverrideOpacity && !paint->getShader()) {
37                 opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity;
38             } else {
39                 opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity;
40             }
41         }
42     }
43 
44     return SkXfermode::IsOpaque(paint->getXfermode(), opacityType);
45 }
46 
Overwrites(const SkBitmap & bitmap,const SkPaint * paint)47 bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) {
48     return Overwrites(paint, bitmap.isOpaque() ? kOpaque_ShaderOverrideOpacity
49                                                : kNotOpaque_ShaderOverrideOpacity);
50 }
51 
Overwrites(const SkImage * image,const SkPaint * paint)52 bool SkPaintPriv::Overwrites(const SkImage* image, const SkPaint* paint) {
53     return Overwrites(paint, image->isOpaque() ? kOpaque_ShaderOverrideOpacity
54                                                : kNotOpaque_ShaderOverrideOpacity);
55 }
56