| /* | |
| * Copyright 2013 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SkPaintPriv.h" | |
| #include "SkBitmap.h" | |
| #include "SkColorFilter.h" | |
| #include "SkPaint.h" | |
| #include "SkShader.h" | |
| bool isPaintOpaque(const SkPaint* paint, | |
| const SkBitmap* bmpReplacesShader) { | |
| // TODO: SkXfermode should have a virtual isOpaque method, which would | |
| // make it possible to test modes that do not have a Coeff representation. | |
| if (!paint) { | |
| return bmpReplacesShader ? bmpReplacesShader->isOpaque() : true; | |
| } | |
| SkXfermode::Coeff srcCoeff, dstCoeff; | |
| if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){ | |
| if (SkXfermode::kDA_Coeff == srcCoeff || SkXfermode::kDC_Coeff == srcCoeff || | |
| SkXfermode::kIDA_Coeff == srcCoeff || SkXfermode::kIDC_Coeff == srcCoeff) { | |
| return false; | |
| } | |
| switch (dstCoeff) { | |
| case SkXfermode::kZero_Coeff: | |
| return true; | |
| case SkXfermode::kISA_Coeff: | |
| if (paint->getAlpha() != 255) { | |
| break; | |
| } | |
| if (bmpReplacesShader) { | |
| if (!bmpReplacesShader->isOpaque()) { | |
| break; | |
| } | |
| } else if (paint->getShader() && !paint->getShader()->isOpaque()) { | |
| break; | |
| } | |
| if (paint->getColorFilter() && | |
| ((paint->getColorFilter()->getFlags() & | |
| SkColorFilter::kAlphaUnchanged_Flag) == 0)) { | |
| break; | |
| } | |
| return true; | |
| case SkXfermode::kSA_Coeff: | |
| if (paint->getAlpha() != 0) { | |
| break; | |
| } | |
| if (paint->getColorFilter() && | |
| ((paint->getColorFilter()->getFlags() & | |
| SkColorFilter::kAlphaUnchanged_Flag) == 0)) { | |
| break; | |
| } | |
| return true; | |
| case SkXfermode::kSC_Coeff: | |
| if (paint->getColor() != 0) { // all components must be 0 | |
| break; | |
| } | |
| if (bmpReplacesShader || paint->getShader()) { | |
| break; | |
| } | |
| if (paint->getColorFilter() && ( | |
| (paint->getColorFilter()->getFlags() & | |
| SkColorFilter::kAlphaUnchanged_Flag) == 0)) { | |
| break; | |
| } | |
| return true; | |
| default: | |
| break; | |
| } | |
| } | |
| return false; | |
| } | |
| bool NeedsDeepCopy(const SkPaint& paint) { | |
| /* | |
| * The types below are not yet immutable/reentrant-safe, and so we return | |
| * true if instances of them are present in the paint. | |
| * | |
| * Eventually we hope this list will be empty, and we can always return | |
| * false. | |
| */ | |
| return paint.getImageFilter(); | |
| } |