SkBlurDrawLooper.cpp revision 4868e6b221a4a98e40f977851af5fcf09631ea15
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurDrawLooper.h" 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurMaskFilter.h" 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 64868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org#include "SkColorFilter.h" 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, 9038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org SkColor color, uint32_t flags) 10038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 12038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org SkASSERT(flags <= kAll_BlurFlag); 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius > 0) 14038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org { 1582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 1682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 17038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org SkBlurMaskFilter::kNone_BlurFlag; 18038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org 194868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org blurFlags |= flags & kHighQuality_BlurFlag ? 204868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org SkBlurMaskFilter::kHighQuality_BlurFlag : 214868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org SkBlurMaskFilter::kNone_BlurFlag; 224868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlur = SkBlurMaskFilter::Create(radius, 244868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org SkBlurMaskFilter::kNormal_BlurStyle, 25038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org blurFlags); 26038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org } 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 284868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org { 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlur = NULL; 304868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org } 314868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org 324868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org if (flags & kOverrideColor_BlurFlag) 334868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org { 344868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org //The SrcIn xfer mode will multiply 'color' by the incoming alpha 354868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fColorFilter = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode); 364868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org } 374868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org else 384868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org { 394868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fColorFilter = NULL; 404868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org } 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDx = buffer.readScalar(); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDy = buffer.readScalar(); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlurColor = buffer.readU32(); 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 494868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 50038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org fBlurFlags = buffer.readU32() & kAll_BlurFlag; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::~SkBlurDrawLooper() 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fBlur); 564868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org SkSafeUnref(fColorFilter); 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(fDx); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(fDy); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write32(fBlurColor); 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeFlattenable(fBlur); 654868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org buffer.writeFlattenable(fColorFilter); 66038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org buffer.write32(fBlurFlags); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint) 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we do nothing if a maskfilter is already installed 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint->getMaskFilter() != NULL) 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fState = kDone; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fState = kBeforeEdge; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas = canvas; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSaveCount = canvas->getSaveCount(); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBlurDrawLooper::next() 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (fState) { 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kBeforeEdge: 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSavedColor = fPaint->getColor(); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setColor(fBlurColor); 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setMaskFilter(fBlur); 904868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fPaint->setColorFilter(fColorFilter); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas->save(SkCanvas::kMatrix_SaveFlag); 92038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org if (fBlurFlags & kIgnoreTransform_BlurFlag) 93038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org { 94038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org SkMatrix transform(fCanvas->getTotalMatrix()); 95038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org transform.postTranslate(fDx, fDy); 96038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org fCanvas->setMatrix(transform); 97038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org } 98038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org else 99038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org { 100038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org fCanvas->translate(fDx, fDy); 101038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org } 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fState = kAfterEdge; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kAfterEdge: 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setColor(fSavedColor); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setMaskFilter(NULL); 1074868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fPaint->setColorFilter(NULL); 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas->restore(); // to remove the translate we did earlier 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fState = kDone; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(kDone == fState); 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::restore() 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (kAfterEdge == fState) 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setColor(fSavedColor); 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint->setMaskFilter(NULL); 1234868e6b221a4a98e40f977851af5fcf09631ea15senorblanco@chromium.org fPaint->setColorFilter(NULL); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas->restore(); // to remove the translate we did earlier 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fState = kDone; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper", 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlurDrawLooper::CreateProc); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134