Home | History | Annotate | Download | only in core
      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