SkBlurDrawLooper.cpp revision 71531ca1f484da5837be8017a0c83e5bff701587
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurDrawLooper.h" 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMaskFilter.h" 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCanvas.h" 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h" 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger#include "SkColorFilter.h" 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, 940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkColor color, uint32_t flags) 1040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= kAll_BlurFlag); 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (radius > 0) 1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger blurFlags |= flags & kHighQuality_BlurFlag ? 2071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kHighQuality_BlurFlag : 2171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 2271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = SkBlurMaskFilter::Create(radius, 2471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNormal_BlurStyle, 2540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger blurFlags); 2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 2871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger { 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = NULL; 3071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 3171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 3271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger if (flags & kOverrideColor_BlurFlag) 3371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger { 3471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger //The SrcIn xfer mode will multiply 'color' by the incoming alpha 3571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode); 3671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 3771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger else 3871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger { 3971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = NULL; 4071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDx = buffer.readScalar(); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDy = buffer.readScalar(); 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurColor = buffer.readU32(); 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 4971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & kAll_BlurFlag; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurDrawLooper::~SkBlurDrawLooper() 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fBlur); 5671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkSafeUnref(fColorFilter); 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDx); 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDy); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurColor); 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFlattenable(fBlur); 6571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger buffer.writeFlattenable(fColorFilter); 6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint) 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we do nothing if a maskfilter is already installed 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (paint->getMaskFilter() != NULL) 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fState = kDone; 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fState = kBeforeEdge; 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint = paint; 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCanvas = canvas; 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSaveCount = canvas->getSaveCount(); 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkBlurDrawLooper::next() 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 8502b2438fea16e164afb80c0a778af46089cefb10Romain Guy SkColor blurColor; 8602b2438fea16e164afb80c0a778af46089cefb10Romain Guy SkAlpha alpha; 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (fState) { 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kBeforeEdge: 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSavedColor = fPaint->getColor(); 9002b2438fea16e164afb80c0a778af46089cefb10Romain Guy blurColor = fBlurColor; 9102b2438fea16e164afb80c0a778af46089cefb10Romain Guy alpha = SkColorGetA(blurColor); 9202b2438fea16e164afb80c0a778af46089cefb10Romain Guy if (alpha == 255) { 9302b2438fea16e164afb80c0a778af46089cefb10Romain Guy blurColor = SkColorSetA(blurColor, fPaint->getAlpha()); 9402b2438fea16e164afb80c0a778af46089cefb10Romain Guy } 9502b2438fea16e164afb80c0a778af46089cefb10Romain Guy fPaint->setColor(blurColor); 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setMaskFilter(fBlur); 9771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fPaint->setColorFilter(fColorFilter); 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCanvas->save(SkCanvas::kMatrix_SaveFlag); 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fBlurFlags & kIgnoreTransform_BlurFlag) 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix transform(fCanvas->getTotalMatrix()); 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger transform.postTranslate(fDx, fDy); 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fCanvas->setMatrix(transform); 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger else 10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fCanvas->translate(fDx, fDy); 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fState = kAfterEdge; 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kAfterEdge: 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setColor(fSavedColor); 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setMaskFilter(NULL); 11471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fPaint->setColorFilter(NULL); 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCanvas->restore(); // to remove the translate we did earlier 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fState = kDone; 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(kDone == fState); 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurDrawLooper::restore() 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (kAfterEdge == fState) 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setColor(fSavedColor); 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setMaskFilter(NULL); 13071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fPaint->setColorFilter(NULL); 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCanvas->restore(); // to remove the translate we did earlier 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fState = kDone; 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper", 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurDrawLooper::CreateProc); 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 141