1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 9cb93a386Sopenharmony_ci#include "src/core/SkColorFilterBase.h" 10cb93a386Sopenharmony_ci#include "src/core/SkColorSpacePriv.h" 11cb93a386Sopenharmony_ci#include "src/core/SkPaintPriv.h" 12cb93a386Sopenharmony_ci#include "src/core/SkXfermodePriv.h" 13cb93a386Sopenharmony_ci#include "src/shaders/SkColorFilterShader.h" 14cb93a386Sopenharmony_ci#include "src/shaders/SkShaderBase.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cistatic bool changes_alpha(const SkPaint& paint) { 17cb93a386Sopenharmony_ci SkColorFilter* cf = paint.getColorFilter(); 18cb93a386Sopenharmony_ci return cf && !as_CFB(cf)->isAlphaUnchanged(); 19cb93a386Sopenharmony_ci} 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_cibool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) { 22cb93a386Sopenharmony_ci if (!paint) { 23cb93a386Sopenharmony_ci // No paint means we default to SRC_OVER, so we overwrite iff our shader-override 24cb93a386Sopenharmony_ci // is opaque, or we don't have one. 25cb93a386Sopenharmony_ci return overrideOpacity != kNotOpaque_ShaderOverrideOpacity; 26cb93a386Sopenharmony_ci } 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci SkXfermode::SrcColorOpacity opacityType = SkXfermode::kUnknown_SrcColorOpacity; 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci if (!changes_alpha(*paint)) { 31cb93a386Sopenharmony_ci const unsigned paintAlpha = paint->getAlpha(); 32cb93a386Sopenharmony_ci if (0xff == paintAlpha && overrideOpacity != kNotOpaque_ShaderOverrideOpacity && 33cb93a386Sopenharmony_ci (!paint->getShader() || paint->getShader()->isOpaque())) 34cb93a386Sopenharmony_ci { 35cb93a386Sopenharmony_ci opacityType = SkXfermode::kOpaque_SrcColorOpacity; 36cb93a386Sopenharmony_ci } else if (0 == paintAlpha) { 37cb93a386Sopenharmony_ci if (overrideOpacity == kNone_ShaderOverrideOpacity && !paint->getShader()) { 38cb93a386Sopenharmony_ci opacityType = SkXfermode::kTransparentBlack_SrcColorOpacity; 39cb93a386Sopenharmony_ci } else { 40cb93a386Sopenharmony_ci opacityType = SkXfermode::kTransparentAlpha_SrcColorOpacity; 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci const auto bm = paint->asBlendMode(); 46cb93a386Sopenharmony_ci if (!bm) { 47cb93a386Sopenharmony_ci return false; // don't know for sure, so we play it safe and return false. 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci return SkXfermode::IsOpaque(bm.value(), opacityType); 50cb93a386Sopenharmony_ci} 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_cibool SkPaintPriv::ShouldDither(const SkPaint& p, SkColorType dstCT) { 53cb93a386Sopenharmony_ci // The paint dither flag can veto. 54cb93a386Sopenharmony_ci if (!p.isDither()) { 55cb93a386Sopenharmony_ci return false; 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci // We always dither 565 or 4444 when requested. 59cb93a386Sopenharmony_ci if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) { 60cb93a386Sopenharmony_ci return true; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci // Otherwise, dither is only needed for non-const paints. 64cb93a386Sopenharmony_ci return p.getImageFilter() || p.getMaskFilter() || 65cb93a386Sopenharmony_ci (p.getShader() && !as_SB(p.getShader())->isConstant()); 66cb93a386Sopenharmony_ci} 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci// return true if the paint is just a single color (i.e. not a shader). If its 69cb93a386Sopenharmony_ci// a shader, then we can't compute a const luminance for it :( 70cb93a386Sopenharmony_cistatic bool just_a_color(const SkPaint& paint, SkColor* color) { 71cb93a386Sopenharmony_ci SkColor c = paint.getColor(); 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci const auto* shader = as_SB(paint.getShader()); 74cb93a386Sopenharmony_ci if (shader && !shader->asLuminanceColor(&c)) { 75cb93a386Sopenharmony_ci return false; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci if (paint.getColorFilter()) { 78cb93a386Sopenharmony_ci c = paint.getColorFilter()->filterColor(c); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci if (color) { 81cb93a386Sopenharmony_ci *color = c; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci return true; 84cb93a386Sopenharmony_ci} 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ciSkColor SkPaintPriv::ComputeLuminanceColor(const SkPaint& paint) { 87cb93a386Sopenharmony_ci SkColor c; 88cb93a386Sopenharmony_ci if (!just_a_color(paint, &c)) { 89cb93a386Sopenharmony_ci c = SkColorSetRGB(0x7F, 0x80, 0x7F); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci return c; 92cb93a386Sopenharmony_ci} 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_civoid SkPaintPriv::RemoveColorFilter(SkPaint* p, SkColorSpace* dstCS) { 95cb93a386Sopenharmony_ci if (SkColorFilter* filter = p->getColorFilter()) { 96cb93a386Sopenharmony_ci if (SkShader* shader = p->getShader()) { 97cb93a386Sopenharmony_ci // SkColorFilterShader will modulate the shader color by paint alpha 98cb93a386Sopenharmony_ci // before applying the filter, so we'll reset it to opaque. 99cb93a386Sopenharmony_ci p->setShader(sk_make_sp<SkColorFilterShader>(sk_ref_sp(shader), 100cb93a386Sopenharmony_ci p->getAlphaf(), 101cb93a386Sopenharmony_ci sk_ref_sp(filter))); 102cb93a386Sopenharmony_ci p->setAlphaf(1.0f); 103cb93a386Sopenharmony_ci } else { 104cb93a386Sopenharmony_ci p->setColor(filter->filterColor4f(p->getColor4f(), sk_srgb_singleton(), dstCS), dstCS); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci p->setColorFilter(nullptr); 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci} 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ciSkScalar SkPaintPriv::ComputeResScaleForStroking(const SkMatrix& matrix) { 111cb93a386Sopenharmony_ci // Not sure how to handle perspective differently, so we just don't try (yet) 112cb93a386Sopenharmony_ci SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]); 113cb93a386Sopenharmony_ci SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]); 114cb93a386Sopenharmony_ci if (SkScalarsAreFinite(sx, sy)) { 115cb93a386Sopenharmony_ci SkScalar scale = std::max(sx, sy); 116cb93a386Sopenharmony_ci if (scale > 0) { 117cb93a386Sopenharmony_ci return scale; 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci return 1; 121cb93a386Sopenharmony_ci} 122