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 8 SkBlurDrawLooper::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 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 15 SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 16 SkBlurMaskFilter::kNone_BlurFlag; 17 18 blurFlags |= flags & kHighQuality_BlurFlag ? 19 SkBlurMaskFilter::kHighQuality_BlurFlag : 20 SkBlurMaskFilter::kNone_BlurFlag; 21 22 fBlur = SkBlurMaskFilter::Create(radius, 23 SkBlurMaskFilter::kNormal_BlurStyle, 24 blurFlags); 25 } else { 26 fBlur = NULL; 27 } 28 29 if (flags & kOverrideColor_BlurFlag) { 30 // Set alpha to 1 for the override since transparency will already 31 // be baked into the blurred mask. 32 SkColor opaqueColor = SkColorSetA(color, 255); 33 //The SrcIn xfer mode will multiply 'color' by the incoming alpha 34 fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, 35 SkXfermode::kSrcIn_Mode); 36 } else { 37 fColorFilter = NULL; 38 } 39 } 40 41 SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) { 42 fDx = buffer.readScalar(); 43 fDy = buffer.readScalar(); 44 fBlurColor = buffer.readU32(); 45 fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 46 fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 47 fBlurFlags = buffer.readU32() & kAll_BlurFlag; 48 } 49 50 SkBlurDrawLooper::~SkBlurDrawLooper() { 51 SkSafeUnref(fBlur); 52 SkSafeUnref(fColorFilter); 53 } 54 55 void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { 56 buffer.writeScalar(fDx); 57 buffer.writeScalar(fDy); 58 buffer.write32(fBlurColor); 59 buffer.writeFlattenable(fBlur); 60 buffer.writeFlattenable(fColorFilter); 61 buffer.write32(fBlurFlags); 62 } 63 64 void SkBlurDrawLooper::init(SkCanvas* canvas) { 65 fState = kBeforeEdge; 66 } 67 68 bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 69 switch (fState) { 70 case kBeforeEdge: 71 // we do nothing if a maskfilter is already installed 72 if (paint->getMaskFilter()) { 73 fState = kDone; 74 return false; 75 } 76 #ifdef ANDROID 77 SkColor blurColor; 78 blurColor = fBlurColor; 79 if (SkColorGetA(blurColor) == 255) { 80 blurColor = SkColorSetA(blurColor, paint->getAlpha()); 81 } 82 paint->setColor(blurColor); 83 #else 84 paint->setColor(fBlurColor); 85 #endif 86 paint->setMaskFilter(fBlur); 87 paint->setColorFilter(fColorFilter); 88 canvas->save(SkCanvas::kMatrix_SaveFlag); 89 if (fBlurFlags & kIgnoreTransform_BlurFlag) { 90 SkMatrix transform(canvas->getTotalMatrix()); 91 transform.postTranslate(fDx, fDy); 92 canvas->setMatrix(transform); 93 } else { 94 canvas->translate(fDx, fDy); 95 } 96 fState = kAfterEdge; 97 return true; 98 case kAfterEdge: 99 canvas->restore(); 100 fState = kDone; 101 return true; 102 default: 103 SkASSERT(kDone == fState); 104 return false; 105 } 106 } 107 108 /////////////////////////////////////////////////////////////////////////////// 109 110 static SkFlattenable::Registrar gReg("SkBlurDrawLooper", 111 SkBlurDrawLooper::CreateProc); 112 113