11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkScalar.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkMallocPixelRef.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::SkShader() : fLocalMatrix(NULL) {
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::SkShader(SkFlattenableReadBuffer& buffer)
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer), fLocalMatrix(NULL) {
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (buffer.readBool()) {
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkMatrix matrix;
2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkReadMatrix(&buffer, &matrix);
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        setLocalMatrix(matrix);
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::~SkShader() {
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!fInSession);
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_free(fLocalMatrix);
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::beginSession() {
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!fInSession);
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = true;)
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::endSession() {
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fInSession);
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) {
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeBool(fLocalMatrix != NULL);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
4835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkWriteMatrix(&buffer, *fLocalMatrix);
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkShader::getLocalMatrix(SkMatrix* localM) const {
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (localM) {
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *localM = *fLocalMatrix;
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (localM) {
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            localM->reset();
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::setLocalMatrix(const SkMatrix& localM) {
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (localM.isIdentity()) {
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->resetLocalMatrix();
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fLocalMatrix == NULL) {
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *fLocalMatrix = localM;
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::resetLocalMatrix() {
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_free(fLocalMatrix);
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fLocalMatrix = NULL;
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkShader::setContext(const SkBitmap& device,
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          const SkPaint& paint,
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          const SkMatrix& matrix) {
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMatrix* m = &matrix;
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix        total;
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDeviceConfig = SkToU8(device.getConfig());
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaintAlpha = paint.getAlpha();
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        total.setConcat(matrix, *fLocalMatrix);
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        m = &total;
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (m->invert(&fTotalInverse)) {
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(span16);
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(this->canCallShadeSpan16());
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // basically, if we get here, the subclass screwed up
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented");
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
11505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#define kTempColorCount     (kTempColorQuadCount << 2)
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_BENDIAN
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkU32BitShiftToByteOffset(shift)    ((shift) >> 3)
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPMColor   colors[kTempColorCount];
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((count -= kTempColorCount) >= 0) {
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, kTempColorCount);
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x += kTempColorCount;
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int quads = kTempColorQuadCount;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a0 = srcA[0];
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a1 = srcA[4];
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a2 = srcA[8];
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a3 = srcA[12];
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4*4;
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a0);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a1);
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a2);
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a3);
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--quads != 0);
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count < 0);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count + kTempColorCount >= 0);
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count += kTempColorCount) {
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, count);
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = *srcA;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4;
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--count != 0);
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int n = count;
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (n > kTempColorCount)
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            n = kTempColorCount;
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(n > 0);
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, n);
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x += n;
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        count -= n;
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = *srcA;
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--n != 0);
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (count > 0);
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) {
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    MatrixClass mc = kLinear_MatrixClass;
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1800199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    if (mat.hasPerspective()) {
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (mat.fixedStepInX(0, NULL, NULL)) {
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            mc = kFixedStepInX_MatrixClass;
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            mc = kPerspective_MatrixClass;
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mc;
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*,
19305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         TileMode*, SkScalar*) const {
19440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return kNone_BitmapType;
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
19805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return kNone_GradientType;
19905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
20005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                       TileMode tmx, TileMode tmy) {
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0);
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h"
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkColorShader::SkColorShader() {
21240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fFlags = 0;
21340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fInheritColor = true;
21440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
21540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
21640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkColorShader::SkColorShader(SkColor c) {
21740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fFlags = 0;
21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fColor = c;
21940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fInheritColor = false;
22040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
22140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2221cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkColorShader::~SkColorShader() {}
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkColorShader::isOpaque() const {
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fInheritColor) {
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true; // using paint's alpha
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return SkColorGetA(fColor) == 255;
22940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
23040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) {
232f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed    fFlags = 0; // computed in setContext
23340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
23440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fInheritColor = b.readU8();
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = b.readU32();
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) {
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(fInheritColor);
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fColor);
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2501cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable* SkColorShader::CreateProc(SkFlattenableReadBuffer& buffer) {
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return SkNEW_ARGS(SkColorShader, (buffer));
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2541cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable::Factory SkColorShader::getFactory() {
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return CreateProc;
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergeruint32_t SkColorShader::getFlags() {
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fFlags;
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint8_t SkColorShader::getSpan16Alpha() const {
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkGetPackedA32(fPMColor);
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const SkMatrix& matrix) {
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!this->INHERITED::setContext(device, paint, matrix)) {
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned a;
27305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
27505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fColor = paint.getColor();
27605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        a = SkColorGetA(fColor);
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
27805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha()));
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    unsigned r = SkColorGetR(fColor);
28205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    unsigned g = SkColorGetG(fColor);
28305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    unsigned b = SkColorGetB(fColor);
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // we want this before we apply any alpha
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor16 = SkPack888ToRGB16(r, g, b);
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (a != 255) {
289967ad142beea3daade8c053a17f7ac83e7e4e267Mike Reed        r = SkMulDiv255Round(r, a);
290967ad142beea3daade8c053a17f7ac83e7e4e267Mike Reed        g = SkMulDiv255Round(g, a);
291967ad142beea3daade8c053a17f7ac83e7e4e267Mike Reed        b = SkMulDiv255Round(b, a);
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPMColor = SkPackARGB32(a, r, g, b);
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
295967ad142beea3daade8c053a17f7ac83e7e4e267Mike Reed    fFlags = kConstInY32_Flag;
2962b95810e4df7c89e07def8891aa8dd9085c29461Mike Reed    if (255 == a) {
297f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed        fFlags |= kOpaqueAlpha_Flag;
2982b95810e4df7c89e07def8891aa8dd9085c29461Mike Reed        if (paint.isDither() == false) {
2992b95810e4df7c89e07def8891aa8dd9085c29461Mike Reed            fFlags |= kHasSpan16_Flag;
3002b95810e4df7c89e07def8891aa8dd9085c29461Mike Reed        }
301f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed    }
302f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_memset32(span, fPMColor, count);
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_memset16(span, fColor16, count);
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memset(alpha, SkGetPackedA32(fPMColor), count);
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// if we had a asAColor method, that would be more efficient...
31940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
32005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                              TileMode modes[],
32105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                      SkScalar* twoPointRadialParams) const {
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return kNone_BitmapType;
32340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
32440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
32505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
32605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (info) {
32705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (info->fColors && info->fColorCount >= 1) {
32805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            info->fColors[0] = fColor;
32905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
33005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        info->fColorCount = 1;
33105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        info->fTileMode = SkShader::kRepeat_TileMode;
33205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
33305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return kColor_GradientType;
33405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkEmptyShader.h"
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3401cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkEmptyShader::SkEmptyShader(SkFlattenableReadBuffer& b) : INHERITED(b) {}
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergeruint32_t SkEmptyShader::getFlags() { return 0; }
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergeruint8_t SkEmptyShader::getSpan16Alpha() const { return 0; }
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&,
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const SkMatrix&) { return false; }
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("should never get called, since setContext() returned false");
3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("should never get called, since setContext() returned false");
3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("should never get called, since setContext() returned false");
3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3601cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable::Factory SkEmptyShader::getFactory() { return NULL; }
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkEmptyShader::flatten(SkFlattenableWriteBuffer& buffer) {
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->INHERITED::flatten(buffer);
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
366