• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
changes_alpha(const SkPaint & paint)14 static bool changes_alpha(const SkPaint& paint) {
15     SkColorFilter* cf = paint.getColorFilter();
16     return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
17 }
18 
Overwrites(const SkPaint * paint,ShaderOverrideOpacity overrideOpacity)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 
ShouldDither(const SkPaint & p,SkColorType dstCT)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 :(
just_a_color(const SkPaint & paint,SkColor * color)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 
ComputeLuminanceColor(const SkPaint & paint)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