SkShader.cpp revision c73dd5c6880739f26216f198c757028fd28df1a4
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org#include "SkScalar.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 12c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com#include "SkFlattenableBuffers.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 14f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkMallocPixelRef.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 160456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.comSK_DEFINE_INST_COUNT(SkShader) 170456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader() : fLocalMatrix(NULL) { 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader(SkFlattenableReadBuffer& buffer) 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(buffer), fLocalMatrix(NULL) { 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 262b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com buffer.readMatrix(&matrix); 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com setLocalMatrix(matrix); 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::beginSession() { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = true;) 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::endSession() { 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fInSession); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4754924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) const { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeBool(fLocalMatrix != NULL); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 512b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com buffer.writeMatrix(*fLocalMatrix); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::getLocalMatrix(SkMatrix* localM) const { 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *localM = *fLocalMatrix; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localM->reset(); 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::setLocalMatrix(const SkMatrix& localM) { 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM.isIdentity()) { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->resetLocalMatrix(); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix == NULL) { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix)); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fLocalMatrix = localM; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::resetLocalMatrix() { 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = NULL; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::setContext(const SkBitmap& device, 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* m = &matrix; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix total; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceConfig = SkToU8(device.getConfig()); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaintAlpha = paint.getAlpha(); 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com total.setConcat(matrix, *fLocalMatrix); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com m = &total; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (m->invert(&fTotalInverse)) { 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1140c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1187c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com#define kTempColorCount (kTempColorQuadCount << 2) 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (mat.hasPerspective()) { 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 195d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 19691f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com TileMode*) const { 197f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 201d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kNone_GradientType; 202d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 203d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 20403c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.comGrCustomStage* SkShader::asNewCustomStage(GrContext* context, 20503c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com GrSamplerState* sampler) const { 20603c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com return NULL; 20703c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com} 20803c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com TileMode tmx, TileMode tmy) { 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0); 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 219f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::SkColorShader() { 220f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fFlags = 0; 221f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = true; 222f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 223f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 224f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::SkColorShader(SkColor c) { 225f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fFlags = 0; 226f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fColor = c; 227f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = false; 228f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 229f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 2302be9e8b407624fa696854b78b407b97a01dbb703reed@google.comSkColorShader::~SkColorShader() {} 231f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 232b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkColorShader::isOpaque() const { 233b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org if (fInheritColor) { 234b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org return true; // using paint's alpha 235b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org } 236b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org return SkColorGetA(fColor) == 255; 237b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org} 238b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) { 2405119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags = 0; // computed in setContext 241f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 242c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fInheritColor = b.readBool(); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 246c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fColor = b.readColor(); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24954924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) const { 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 251c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeBool(fInheritColor); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 255c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColor(fColor); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25859ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.comuint32_t SkColorShader::getFlags() { 25959ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com return fFlags; 26059ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 26159ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint8_t SkColorShader::getSpan16Alpha() const { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->INHERITED::setContext(device, paint, matrix)) { 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a; 273d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 275d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org fColor = paint.getColor(); 276d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org a = SkColorGetA(fColor); 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 278d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 281d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned r = SkColorGetR(fColor); 282d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned g = SkColorGetG(fColor); 283d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned b = SkColorGetB(fColor); 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 2898f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 2908f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 2918f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2958f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 2965b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 2975119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 2985b81535014f545f6498f5c8721723b81576989b1reed@android.com if (paint.isDither() == false) { 2995b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 3005b81535014f545f6498f5c8721723b81576989b1reed@android.com } 3015119bdb952025a30f115b9c6a187173956e55097reed@android.com } 3025119bdb952025a30f115b9c6a187173956e55097reed@android.com 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 319f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 32091f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com TileMode modes[]) const { 3212be9e8b407624fa696854b78b407b97a01dbb703reed@google.com return kNone_BitmapType; 322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 323f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 324d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 325d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info) { 326d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info->fColors && info->fColorCount >= 1) { 327d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColors[0] = fColor; 328d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 329d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColorCount = 1; 330d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fTileMode = SkShader::kRepeat_TileMode; 331d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 332d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kColor_GradientType; 333d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 33437a201231b8f6381938282675eb9abb50ab3b389reed@google.com 335a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkColorShader) 336a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com 33737a201231b8f6381938282675eb9abb50ab3b389reed@google.com/////////////////////////////////////////////////////////////////////////////// 33837a201231b8f6381938282675eb9abb50ab3b389reed@google.com 33937a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h" 34037a201231b8f6381938282675eb9abb50ab3b389reed@google.com 34137a201231b8f6381938282675eb9abb50ab3b389reed@google.comuint32_t SkEmptyShader::getFlags() { return 0; } 34237a201231b8f6381938282675eb9abb50ab3b389reed@google.comuint8_t SkEmptyShader::getSpan16Alpha() const { return 0; } 34359ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 34459ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.combool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&, 34559ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com const SkMatrix&) { return false; } 34659ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 34759ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.comvoid SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 3480c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("should never get called, since setContext() returned false"); 34959ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 35059ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 35159ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.comvoid SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 3520c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("should never get called, since setContext() returned false"); 35359ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 35459ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 35559ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.comvoid SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3560c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("should never get called, since setContext() returned false"); 35737a201231b8f6381938282675eb9abb50ab3b389reed@google.com} 35837a201231b8f6381938282675eb9abb50ab3b389reed@google.com 359a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkEmptyShader) 360