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