SkBlurDrawLooper.cpp revision 4868e6b221a4a98e40f977851af5fcf09631ea15
1#include "SkBlurDrawLooper.h" 2#include "SkBlurMaskFilter.h" 3#include "SkCanvas.h" 4#include "SkPaint.h" 5#include "SkMaskFilter.h" 6#include "SkColorFilter.h" 7 8SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, 9 SkColor color, uint32_t flags) 10 : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) 11{ 12 SkASSERT(flags <= kAll_BlurFlag); 13 if (radius > 0) 14 { 15 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 16 SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 17 SkBlurMaskFilter::kNone_BlurFlag; 18 19 blurFlags |= flags & kHighQuality_BlurFlag ? 20 SkBlurMaskFilter::kHighQuality_BlurFlag : 21 SkBlurMaskFilter::kNone_BlurFlag; 22 23 fBlur = SkBlurMaskFilter::Create(radius, 24 SkBlurMaskFilter::kNormal_BlurStyle, 25 blurFlags); 26 } 27 else 28 { 29 fBlur = NULL; 30 } 31 32 if (flags & kOverrideColor_BlurFlag) 33 { 34 //The SrcIn xfer mode will multiply 'color' by the incoming alpha 35 fColorFilter = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode); 36 } 37 else 38 { 39 fColorFilter = NULL; 40 } 41} 42 43SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) 44{ 45 fDx = buffer.readScalar(); 46 fDy = buffer.readScalar(); 47 fBlurColor = buffer.readU32(); 48 fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 49 fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 50 fBlurFlags = buffer.readU32() & kAll_BlurFlag; 51} 52 53SkBlurDrawLooper::~SkBlurDrawLooper() 54{ 55 SkSafeUnref(fBlur); 56 SkSafeUnref(fColorFilter); 57} 58 59void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) 60{ 61 buffer.writeScalar(fDx); 62 buffer.writeScalar(fDy); 63 buffer.write32(fBlurColor); 64 buffer.writeFlattenable(fBlur); 65 buffer.writeFlattenable(fColorFilter); 66 buffer.write32(fBlurFlags); 67} 68 69void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint) 70{ 71 // we do nothing if a maskfilter is already installed 72 if (paint->getMaskFilter() != NULL) 73 fState = kDone; 74 else 75 { 76 fState = kBeforeEdge; 77 fPaint = paint; 78 fCanvas = canvas; 79 fSaveCount = canvas->getSaveCount(); 80 } 81} 82 83bool SkBlurDrawLooper::next() 84{ 85 switch (fState) { 86 case kBeforeEdge: 87 fSavedColor = fPaint->getColor(); 88 fPaint->setColor(fBlurColor); 89 fPaint->setMaskFilter(fBlur); 90 fPaint->setColorFilter(fColorFilter); 91 fCanvas->save(SkCanvas::kMatrix_SaveFlag); 92 if (fBlurFlags & kIgnoreTransform_BlurFlag) 93 { 94 SkMatrix transform(fCanvas->getTotalMatrix()); 95 transform.postTranslate(fDx, fDy); 96 fCanvas->setMatrix(transform); 97 } 98 else 99 { 100 fCanvas->translate(fDx, fDy); 101 } 102 fState = kAfterEdge; 103 return true; 104 case kAfterEdge: 105 fPaint->setColor(fSavedColor); 106 fPaint->setMaskFilter(NULL); 107 fPaint->setColorFilter(NULL); 108 fCanvas->restore(); // to remove the translate we did earlier 109 fState = kDone; 110 return true; 111 default: 112 SkASSERT(kDone == fState); 113 return false; 114 } 115} 116 117void SkBlurDrawLooper::restore() 118{ 119 if (kAfterEdge == fState) 120 { 121 fPaint->setColor(fSavedColor); 122 fPaint->setMaskFilter(NULL); 123 fPaint->setColorFilter(NULL); 124 fCanvas->restore(); // to remove the translate we did earlier 125 fState = kDone; 126 } 127} 128 129/////////////////////////////////////////////////////////////////////////////// 130 131static SkFlattenable::Registrar gReg("SkBlurDrawLooper", 132 SkBlurDrawLooper::CreateProc); 133 134