SkBlurDrawLooper.cpp revision 87b8e645865f9633f410c02252a0fd3feb18f09b
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) 1087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) { 1187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= kAll_BlurFlag); 1387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (radius > 0) { 1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger blurFlags |= flags & kHighQuality_BlurFlag ? 1971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kHighQuality_BlurFlag : 2071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 2171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = SkBlurMaskFilter::Create(radius, 2371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNormal_BlurStyle, 2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger blurFlags); 2587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = NULL; 2771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 2871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 2987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (flags & kOverrideColor_BlurFlag) { 30137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // Set alpha to 1 for the override since transparency will already 31137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // be baked into the blurred mask. 32137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger SkColor opaqueColor = SkColorSetA(color, 255); 3371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger //The SrcIn xfer mode will multiply 'color' by the incoming alpha 3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, 3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkXfermode::kSrcIn_Mode); 3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = NULL; 3871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) { 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDx = buffer.readScalar(); 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDy = buffer.readScalar(); 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurColor = buffer.readU32(); 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 4671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & kAll_BlurFlag; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5087b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkBlurDrawLooper::~SkBlurDrawLooper() { 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fBlur); 5271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkSafeUnref(fColorFilter); 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDx); 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDy); 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurColor); 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFlattenable(fBlur); 6071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger buffer.writeFlattenable(fColorFilter); 6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::init(SkCanvas* canvas) { 6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kBeforeEdge; 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (fState) { 7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger case kBeforeEdge: 7187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger // we do nothing if a maskfilter is already installed 7287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (paint->getMaskFilter()) { 7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kDone; 7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return false; 7587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#ifdef ANDROID 7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkColor blurColor; 7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger blurColor = fBlurColor; 7987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (SkColorGetA(blurColor) == 255) { 8087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger blurColor = SkColorSetA(blurColor, paint->getAlpha()); 8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColor(blurColor); 8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else 8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColor(fBlurColor); 8587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 8687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setMaskFilter(fBlur); 8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColorFilter(fColorFilter); 8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->save(SkCanvas::kMatrix_SaveFlag); 8987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (fBlurFlags & kIgnoreTransform_BlurFlag) { 9087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkMatrix transform(canvas->getTotalMatrix()); 9187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger transform.postTranslate(fDx, fDy); 9287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->setMatrix(transform); 9387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 9487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->translate(fDx, fDy); 9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kAfterEdge; 9787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return true; 9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger case kAfterEdge: 9987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->restore(); 10087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kDone; 10187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return true; 10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger default: 10387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkASSERT(kDone == fState); 10487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return false; 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper", 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurDrawLooper::CreateProc); 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113