1baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org/*
2baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org * Copyright 2013 Google Inc.
3baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org *
4baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org * Use of this source code is governed by a BSD-style license that can be
5baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org * found in the LICENSE file.
6baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org */
7baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org
8baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkPaintPriv.h"
9baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org
10baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkBitmap.h"
11baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkColorFilter.h"
12baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkPaint.h"
13baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkShader.h"
14baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org
15baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.orgbool isPaintOpaque(const SkPaint* paint,
16baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                   const SkBitmap* bmpReplacesShader) {
17baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    // TODO: SkXfermode should have a virtual isOpaque method, which would
18baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    // make it possible to test modes that do not have a Coeff representation.
19baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org
20baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    if (!paint) {
21baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        return bmpReplacesShader ? bmpReplacesShader->isOpaque() : true;
22baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    }
23baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org
24baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    SkXfermode::Coeff srcCoeff, dstCoeff;
25baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){
26baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        if (SkXfermode::kDA_Coeff == srcCoeff || SkXfermode::kDC_Coeff == srcCoeff ||
27baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            SkXfermode::kIDA_Coeff == srcCoeff || SkXfermode::kIDC_Coeff == srcCoeff) {
28baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            return false;
29baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        }
30baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        switch (dstCoeff) {
31baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        case SkXfermode::kZero_Coeff:
32baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            return true;
33baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        case SkXfermode::kISA_Coeff:
34baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getAlpha() != 255) {
35baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
36baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
37baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (bmpReplacesShader) {
38baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                if (!bmpReplacesShader->isOpaque()) {
39baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                    break;
40baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                }
41baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            } else if (paint->getShader() && !paint->getShader()->isOpaque()) {
42baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
43baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
44baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getColorFilter() &&
45baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                ((paint->getColorFilter()->getFlags() &
46baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
47baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
48baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
49baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            return true;
50baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        case SkXfermode::kSA_Coeff:
51baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getAlpha() != 0) {
52baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
53baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
54baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getColorFilter() &&
55baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                ((paint->getColorFilter()->getFlags() &
56baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
57baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
58baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
59baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            return true;
60baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        case SkXfermode::kSC_Coeff:
61baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getColor() != 0) { // all components must be 0
62baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
63baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
64baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (bmpReplacesShader || paint->getShader()) {
65baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
66baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
67baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            if (paint->getColorFilter() && (
68baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                (paint->getColorFilter()->getFlags() &
69baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
70baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org                break;
71baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            }
72baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            return true;
73baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        default:
74baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org            break;
75baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org        }
76baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    }
77baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org    return false;
78baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org}
790205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org
800205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.orgbool NeedsDeepCopy(const SkPaint& paint) {
810205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org    /*
829cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org     *  The types below are not yet immutable/reentrant-safe, and so we return
839cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org     *  true if instances of them are present in the paint.
840205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org     *
859cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org     *  Eventually we hope this list will be empty, and we can always return
869cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org     *  false.
870205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org     */
889cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org    return false
899cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX
909cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org           || paint.getShader()
919cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org#endif
920205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
939cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org           || paint.getRasterizer()
940205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org#endif
959cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org           || paint.getImageFilter()
969cb4283401f0acf117de523b4b676eca293d7143commit-bot@chromium.org           ;
970205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org}
98