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 "SkColorFilter.h" 9 #include "SkPaintPriv.h" 10 #include "SkPaint.h" 11 #include "SkShaderBase.h" 12 #include "SkXfermodePriv.h" 13 14 static bool changes_alpha(const SkPaint& paint) { 15 SkColorFilter* cf = paint.getColorFilter(); 16 return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); 17 } 18 19 bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) { 20 if (!paint) { 21 // No paint means we default to SRC_OVER, so we overwrite iff our shader-override 22 // is opaque, or we don't have one. 23 return overrideOpacity != kNotOpaque_ShaderOverrideOpacity; 24 } 25 26 SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity; 27 28 if (!changes_alpha(*paint)) { 29 const unsigned paintAlpha = paint->getAlpha(); 30 if (0xff == paintAlpha && overrideOpacity != kNotOpaque_ShaderOverrideOpacity && 31 (!paint->getShader() || paint->getShader()->isOpaque())) 32 { 33 opacityType = SkXfermode::kOpaque_SrcColorOpacity; 34 } else if (0 == paintAlpha) { 35 if (overrideOpacity == kNone_ShaderOverrideOpacity && !paint->getShader()) { 36 opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity; 37 } else { 38 opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity; 39 } 40 } 41 } 42 43 return SkXfermode::IsOpaque(paint->getBlendMode(), opacityType); 44 } 45 46 bool SkPaintPriv::ShouldDither(const SkPaint& p, SkColorType dstCT) { 47 // The paint dither flag can veto. 48 if (!p.isDither()) { 49 return false; 50 } 51 52 // We always dither 565 or 4444 when requested. 53 if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) { 54 return true; 55 } 56 57 // Otherwise, dither is only needed for non-const paints. 58 return p.getImageFilter() || p.getMaskFilter() 59 || !p.getShader() || !as_SB(p.getShader())->isConstant(); 60 } 61 62 // return true if the paint is just a single color (i.e. not a shader). If its 63 // a shader, then we can't compute a const luminance for it :( 64 static bool just_a_color(const SkPaint& paint, SkColor* color) { 65 SkColor c = paint.getColor(); 66 67 const auto* shader = as_SB(paint.getShader()); 68 if (shader && !shader->asLuminanceColor(&c)) { 69 return false; 70 } 71 if (paint.getColorFilter()) { 72 c = paint.getColorFilter()->filterColor(c); 73 } 74 if (color) { 75 *color = c; 76 } 77 return true; 78 } 79 80 SkColor SkPaintPriv::ComputeLuminanceColor(const SkPaint& paint) { 81 SkColor c; 82 if (!just_a_color(paint, &c)) { 83 c = SkColorSetRGB(0x7F, 0x80, 0x7F); 84 } 85 return c; 86 } 87