SkShader.cpp revision 7c2f27d788fff9dbf66a6d52753e47f786a313c0
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* libs/graphics/sgl/SkShader.cpp 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Copyright 2006, The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 57c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** Licensed under the Apache License, Version 2.0 (the "License"); 67c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** you may not use this file except in compliance with the License. 77c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** You may obtain a copy of the License at 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 97c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** http://www.apache.org/licenses/LICENSE-2.0 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 117c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** Unless required by applicable law or agreed to in writing, software 127c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** distributed under the License is distributed on an "AS IS" BASIS, 137c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 147c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com** See the License for the specific language governing permissions and 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** limitations under the License. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org#include "SkScalar.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 21f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkMallocPixelRef.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader() : fLocalMatrix(NULL) { 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader(SkFlattenableReadBuffer& buffer) 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(buffer), fLocalMatrix(NULL) { 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.read(&matrix, sizeof(matrix)); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com setLocalMatrix(matrix); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::beginSession() { 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = true;) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::endSession() { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fInSession); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) { 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeBool(fLocalMatrix != NULL); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeMul4(fLocalMatrix, sizeof(SkMatrix)); 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::getLocalMatrix(SkMatrix* localM) const { 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *localM = *fLocalMatrix; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localM->reset(); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::setLocalMatrix(const SkMatrix& localM) { 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM.isIdentity()) { 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->resetLocalMatrix(); 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix == NULL) { 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix)); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fLocalMatrix = localM; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::resetLocalMatrix() { 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = NULL; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::setContext(const SkBitmap& device, 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* m = &matrix; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix total; 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceConfig = SkToU8(device.getConfig()); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaintAlpha = paint.getAlpha(); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com total.setConcat(matrix, *fLocalMatrix); 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com m = &total; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (m->invert(&fTotalInverse)) { 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1237c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com#define kTempColorCount (kTempColorQuadCount << 2) 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.getType() & SkMatrix::kPerspective_Mask) { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 2017c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com TileMode*, SkScalar*) const { 202f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 206d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kNone_GradientType; 207d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 208d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 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 fAsABitmapPixelRef = NULL; 223f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 224f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 225f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::SkColorShader(SkColor c) { 226f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fFlags = 0; 227f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fColor = c; 228f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = false; 229f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = NULL; 230f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 231f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 232f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::~SkColorShader() { 233f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkSafeUnref(fAsABitmapPixelRef); 234f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 235f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) { 2375119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags = 0; // computed in setContext 238f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = NULL; 239f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 240f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = b.readU8(); 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor = b.readU32(); 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) { 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write8(fInheritColor); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write32(fColor); 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint8_t SkColorShader::getSpan16Alpha() const { 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->INHERITED::setContext(device, paint, matrix)) { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a; 267d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 269d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org fColor = paint.getColor(); 270d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org a = SkColorGetA(fColor); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 272d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 275d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned r = SkColorGetR(fColor); 276d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned g = SkColorGetG(fColor); 277d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org unsigned b = SkColorGetB(fColor); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 2838f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 2848f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 2858f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2898f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 2905b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 2915119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 2925b81535014f545f6498f5c8721723b81576989b1reed@android.com if (paint.isDither() == false) { 2935b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 2945b81535014f545f6498f5c8721723b81576989b1reed@android.com } 2955119bdb952025a30f115b9c6a187173956e55097reed@android.com } 2965119bdb952025a30f115b9c6a187173956e55097reed@android.com 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 312f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 313f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 3147c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com TileMode modes[], 315f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkScalar* twoPointRadialParams) { 316f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // we cache the pixelref, since its generateID is used in the texture cache 317f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (NULL == fAsABitmapPixelRef) { 318f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkPMColor* storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor)); 319f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com *storage = fPMColor; 320f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = new SkMallocPixelRef(storage, sizeof(SkPMColor), 321f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com NULL); 322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 3237c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com 324f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (bitmap) { 325f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com bitmap->setPixelRef(fAsABitmapPixelRef); 327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 328f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (matrix) { 329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com matrix->reset(); 330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 331f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (modes) { 332f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com modes[0] = modes[1] = SkShader::kRepeat_TileMode; 333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 334f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kDefault_BitmapType; 335f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 336f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 337d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 338d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info) { 339d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info->fColors && info->fColorCount >= 1) { 340d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColors[0] = fColor; 341d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 342d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColorCount = 1; 343d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fTileMode = SkShader::kRepeat_TileMode; 344d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 345d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kColor_GradientType; 346d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 347