180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScalar.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkShader.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPaint.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMallocPixelRef.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(SkShader)
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkShader::SkShader() {
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fLocalMatrix.reset();
20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkDEBUGCODE(fInSetContext = false;)
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::SkShader(SkFlattenableReadBuffer& buffer)
24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        : INHERITED(buffer) {
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (buffer.readBool()) {
26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        buffer.readMatrix(&fLocalMatrix);
27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    } else {
28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        fLocalMatrix.reset();
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkDEBUGCODE(fInSetContext = false;)
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkShader::~SkShader() {
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkASSERT(!fInSetContext);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) const {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(buffer);
40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    bool hasLocalM = this->hasLocalMatrix();
41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    buffer.writeBool(hasLocalM);
42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (hasLocalM) {
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        buffer.writeMatrix(fLocalMatrix);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkShader::setContext(const SkBitmap& device,
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                          const SkPaint& paint,
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                          const SkMatrix& matrix) {
50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkASSERT(!this->setContextHasBeenCalled());
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMatrix* m = &matrix;
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix        total;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fDeviceConfig = SkToU8(device.getConfig());
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPaintAlpha = paint.getAlpha();
57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (this->hasLocalMatrix()) {
58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        total.setConcat(matrix, this->getLocalMatrix());
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        m = &total;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (m->invert(&fTotalInverse)) {
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkDEBUGCODE(fInSetContext = true;)
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkShader::endContext() {
70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkASSERT(fInSetContext);
71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkDEBUGCODE(fInSetContext = false;)
72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::ShadeProc SkShader::asAShadeProc(void** ctx) {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return NULL;
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(span16);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count > 0);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(this->canCallShadeSpan16());
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // basically, if we get here, the subclass screwed up
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented");
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define kTempColorCount     (kTempColorQuadCount << 2)
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_CPU_BENDIAN
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkU32BitShiftToByteOffset(shift)    ((shift) >> 3)
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count > 0);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPMColor   colors[kTempColorCount];
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while ((count -= kTempColorCount) >= 0) {
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->shadeSpan(x, y, colors, kTempColorCount);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += kTempColorCount;
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int quads = kTempColorQuadCount;
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        do {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            U8CPU a0 = srcA[0];
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            U8CPU a1 = srcA[4];
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            U8CPU a2 = srcA[8];
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            U8CPU a3 = srcA[12];
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            srcA += 4*4;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = SkToU8(a0);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = SkToU8(a1);
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = SkToU8(a2);
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = SkToU8(a3);
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } while (--quads != 0);
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count < 0);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count + kTempColorCount >= 0);
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (count += kTempColorCount) {
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->shadeSpan(x, y, colors, count);
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        do {
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = *srcA;
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            srcA += 4;
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } while (--count != 0);
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    do {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int n = count;
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (n > kTempColorCount)
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            n = kTempColorCount;
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(n > 0);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->shadeSpan(x, y, colors, n);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += n;
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        count -= n;
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        do {
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *alpha++ = *srcA;
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            srcA += 4;
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } while (--n != 0);
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } while (count > 0);
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) {
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    MatrixClass mc = kLinear_MatrixClass;
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mat.hasPerspective()) {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (mat.fixedStepInX(0, NULL, NULL)) {
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            mc = kFixedStepInX_MatrixClass;
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            mc = kPerspective_MatrixClass;
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return mc;
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*,
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         TileMode*) const {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return kNone_BitmapType;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return kNone_GradientType;
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
176d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const {
177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return NULL;
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                       TileMode tmx, TileMode tmy) {
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
185d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER
186d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkShader::toString(SkString* str) const {
187d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (this->hasLocalMatrix()) {
188d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        str->append(" ");
189d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        this->getLocalMatrix().toString(str);
190d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
191d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
192d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
193d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorShader.h"
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkUtils.h"
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorShader::SkColorShader() {
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fFlags = 0;
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInheritColor = true;
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorShader::SkColorShader(SkColor c) {
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fFlags = 0;
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColor = c;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInheritColor = false;
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorShader::~SkColorShader() {}
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkColorShader::isOpaque() const {
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fInheritColor) {
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true; // using paint's alpha
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkColorGetA(fColor) == 255;
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) {
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fFlags = 0; // computed in setContext
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInheritColor = b.readBool();
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fInheritColor) {
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColor = b.readColor();
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) const {
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(buffer);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeBool(fInheritColor);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fInheritColor) {
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeColor(fColor);
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t SkColorShader::getFlags() {
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fFlags;
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint8_t SkColorShader::getSpan16Alpha() const {
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkGetPackedA32(fPMColor);
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               const SkMatrix& matrix) {
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!this->INHERITED::setContext(device, paint, matrix)) {
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned a;
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fInheritColor) {
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fColor = paint.getColor();
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a = SkColorGetA(fColor);
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha()));
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned r = SkColorGetR(fColor);
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned g = SkColorGetG(fColor);
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned b = SkColorGetB(fColor);
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // we want this before we apply any alpha
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColor16 = SkPack888ToRGB16(r, g, b);
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (a != 255) {
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r = SkMulDiv255Round(r, a);
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        g = SkMulDiv255Round(g, a);
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b = SkMulDiv255Round(b, a);
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPMColor = SkPackARGB32(a, r, g, b);
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fFlags = kConstInY32_Flag;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (255 == a) {
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fFlags |= kOpaqueAlpha_Flag;
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (paint.isDither() == false) {
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fFlags |= kHasSpan16_Flag;
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sk_memset32(span, fPMColor, count);
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sk_memset16(span, fColor16, count);
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memset(alpha, SkGetPackedA32(fPMColor), count);
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// if we had a asAColor method, that would be more efficient...
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              TileMode modes[]) const {
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return kNone_BitmapType;
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (info) {
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (info->fColors && info->fColorCount >= 1) {
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            info->fColors[0] = fColor;
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        info->fColorCount = 1;
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        info->fTileMode = SkShader::kRepeat_TileMode;
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return kColor_GradientType;
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
315d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER
316d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkColorShader::toString(SkString* str) const {
317d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    str->append("SkColorShader: (");
318d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
319d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (fInheritColor) {
320d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        str->append("Color: inherited from paint");
321d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    } else {
322d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        str->append("Color: ");
323d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        str->appendHex(fColor);
324d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
325d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
326d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->INHERITED::toString(str);
327d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
328d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    str->append(")");
329d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
330d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
331d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkEmptyShader.h"
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t SkEmptyShader::getFlags() { return 0; }
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint8_t SkEmptyShader::getSpan16Alpha() const { return 0; }
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&,
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               const SkMatrix&) { return false; }
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGFAIL("should never get called, since setContext() returned false");
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGFAIL("should never get called, since setContext() returned false");
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGFAIL("should never get called, since setContext() returned false");
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
353d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
354d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER
355d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkEmptyShader::toString(SkString* str) const {
356d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    str->append("SkEmptyShader: (");
357d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
358d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->INHERITED::toString(str);
359d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
360d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    str->append(")");
361d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
362d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
363