SkShader.cpp revision f3e505984d08fb96e753be2b561f479dc3a4c544
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 8a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkBitmapProcShader.h" 9a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkReadBuffer.h" 10a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkMallocPixelRef.h" 11a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkPaint.h" 12c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPicture.h" 13c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPictureShader.h" 14d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org#include "SkScalar.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 189c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkShader::SkShader(const SkMatrix* localMatrix) { 199c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org if (localMatrix) { 209c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org fLocalMatrix = *localMatrix; 219c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org } else { 229c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org fLocalMatrix.reset(); 239c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org } 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkShader::SkShader(SkReadBuffer& buffer) 27f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com : INHERITED(buffer) { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 29f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.readMatrix(&fLocalMatrix); 30f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com } else { 31f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com fLocalMatrix.reset(); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkShader::flatten(SkWriteBuffer& buffer) const { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 40f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com bool hasLocalM = this->hasLocalMatrix(); 41f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeBool(hasLocalM); 42f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com if (hasLocalM) { 43f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeMatrix(fLocalMatrix); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgbool SkShader::computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInverse) const { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* m = &matrix; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix total; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 51f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com if (this->hasLocalMatrix()) { 52f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com total.setConcat(matrix, this->getLocalMatrix()); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com m = &total; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 5687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return m->invert(totalInverse); 5787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 5887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 5987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgbool SkShader::validContext(const SkBitmap& device, 6087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, 6187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkMatrix& matrix, 6287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkMatrix* totalInverse) const { 6387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return this->computeTotalInverse(matrix, totalInverse); 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 66f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.orgSkShader::Context* SkShader::createContext(const SkBitmap&, const SkPaint&, const SkMatrix&, 67f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org void* storage) const { 68f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return NULL; 69f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 70f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 71f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.orgsize_t SkShader::contextSize() const { 72f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return 0; 73f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 74f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 7587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::Context(const SkShader& shader, const SkBitmap& device, 7687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, const SkMatrix& matrix) 7787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org : fShader(shader) 7887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 7987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fShader.validContext(device, paint, matrix)); 8087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 8187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Because the context parameters must be valid at this point, we know that the matrix is 8287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // invertible. 8387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkAssertResult(fShader.computeTotalInverse(matrix, &fTotalInverse)); 8487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 8587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 8687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fPaintAlpha = paint.getAlpha(); 87a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com} 88a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com 8987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::~Context() {} 9087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 9187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) { 923bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com return NULL; 933bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com} 943bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpan16(int x, int y, uint16_t span16[], int count) { 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1030c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1077c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com#define kTempColorCount (kTempColorQuadCount << 2) 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1728d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (mat.hasPerspective()) { 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) const { 185f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 189d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kNone_GradientType; 190d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 191d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 1920ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.comGrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { 193a3bdc1a6cd1ce9630df43a28fffef17a12c41f32humper@google.com return NULL; 19403c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com} 19503c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com 1969c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, 1979c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org const SkMatrix* localMatrix) { 1989c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL); 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 201c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.orgSkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy) { 202c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org return SkPictureShader::Create(src, tmx, tmy); 203c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org} 204c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org 2050f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 20676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkShader::toString(SkString* str) const { 20776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com if (this->hasLocalMatrix()) { 20876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(" "); 20976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->getLocalMatrix().toString(str); 21076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 21176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 21276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 21376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::SkColorShader(SkColor c) 22076a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org : fColor(c) { 221f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 222f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 223b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkColorShader::isOpaque() const { 224b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org return SkColorGetA(fColor) == 255; 225b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org} 226b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org 2278b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 22876a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's 22976a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // color. We don't support that any more. 23076a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org if (b.pictureVersion() < 26 && 0 != b.pictureVersion()) { 23176a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org if (b.readBool()) { 23276a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org SkDEBUGFAIL("We shouldn't have pictures that recorded the inherited case."); 23376a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org fColor = SK_ColorWHITE; 23476a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org return; 23576a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org } 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 237c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fColor = b.readColor(); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2408b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkColorShader::flatten(SkWriteBuffer& buffer) const { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 242c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColor(fColor); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint32_t SkColorShader::ColorShaderContext::getFlags() const { 24659ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com return fFlags; 24759ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 24859ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 24987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const { 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context* SkColorShader::createContext(const SkBitmap& device, const SkPaint& paint, 25487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkMatrix& matrix, void* storage) const { 25587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (!this->validContext(device, paint, matrix)) { 25687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return NULL; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, device, paint, matrix)); 26087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 26187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, 26387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkBitmap& device, 26487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPaint& paint, 26587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkMatrix& matrix) 26687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org : INHERITED(shader, device, paint, matrix) 26787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 2689c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org SkColor color = shader.fColor; 2699c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha())); 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned r = SkColorGetR(color); 27287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned g = SkColorGetG(color); 27387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned b = SkColorGetB(color); 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 2798f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 2808f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 2818f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2858f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 2865b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 2875119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 2885b81535014f545f6498f5c8721723b81576989b1reed@android.com if (paint.isDither() == false) { 2895b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 2905b81535014f545f6498f5c8721723b81576989b1reed@android.com } 2915119bdb952025a30f115b9c6a187173956e55097reed@android.com } 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[], int count) { 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 306f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 307f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 30891f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com TileMode modes[]) const { 3092be9e8b407624fa696854b78b407b97a01dbb703reed@google.com return kNone_BitmapType; 310f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 311f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 312d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 313d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info) { 314d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info->fColors && info->fColorCount >= 1) { 315d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColors[0] = fColor; 316d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 317d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColorCount = 1; 318d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fTileMode = SkShader::kRepeat_TileMode; 319d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 320d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kColor_GradientType; 321d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 32237a201231b8f6381938282675eb9abb50ab3b389reed@google.com 3230f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 32476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkColorShader::toString(SkString* str) const { 32576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkColorShader: ("); 32676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 32776a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->append("Color: "); 32876a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->appendHex(fColor); 32976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 33076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 33176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 33276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 33376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 33476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 33576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 33637a201231b8f6381938282675eb9abb50ab3b389reed@google.com/////////////////////////////////////////////////////////////////////////////// 33737a201231b8f6381938282675eb9abb50ab3b389reed@google.com 33887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 33937a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h" 34037a201231b8f6381938282675eb9abb50ab3b389reed@google.com 34176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkEmptyShader::toString(SkString* str) const { 34276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkEmptyShader: ("); 34376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 34476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 34576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 34676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 34776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 34876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 349