SkBlurDrawLooper.cpp revision 336b4da6b0d20f27f9980b03415354a2f0698e18
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkBlurDrawLooper.h" 9#include "SkBlurMaskFilter.h" 10#include "SkCanvas.h" 11#include "SkFlattenableBuffers.h" 12#include "SkPaint.h" 13#include "SkMaskFilter.h" 14#include "SkColorFilter.h" 15 16SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, 17 SkColor color, uint32_t flags) 18 : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags), fState(kDone) { 19 20 SkASSERT(flags <= kAll_BlurFlag); 21 if (radius > 0) { 22 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 23 SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 24 SkBlurMaskFilter::kNone_BlurFlag; 25 26 blurFlags |= flags & kHighQuality_BlurFlag ? 27 SkBlurMaskFilter::kHighQuality_BlurFlag : 28 SkBlurMaskFilter::kNone_BlurFlag; 29 30 blurFlags |= flags & kCoarseRadius_BlurFlag ? 31 SkBlurMaskFilter::kCoarseRadius_BlurFlag : 32 SkBlurMaskFilter::kNone_BlurFlag; 33 34 fBlur = SkBlurMaskFilter::Create(radius, 35 SkBlurMaskFilter::kNormal_BlurStyle, 36 blurFlags); 37 } else { 38 fBlur = NULL; 39 } 40 41 if (flags & kOverrideColor_BlurFlag) { 42 // Set alpha to 1 for the override since transparency will already 43 // be baked into the blurred mask. 44 SkColor opaqueColor = SkColorSetA(color, 255); 45 //The SrcIn xfer mode will multiply 'color' by the incoming alpha 46 fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, 47 SkXfermode::kSrcIn_Mode); 48 } else { 49 fColorFilter = NULL; 50 } 51} 52 53SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) 54: INHERITED(buffer) { 55 56 fDx = buffer.readScalar(); 57 fDy = buffer.readScalar(); 58 fBlurColor = buffer.readColor(); 59 fBlur = buffer.readFlattenableT<SkMaskFilter>(); 60 fColorFilter = buffer.readFlattenableT<SkColorFilter>(); 61 fBlurFlags = buffer.readUInt() & kAll_BlurFlag; 62} 63 64SkBlurDrawLooper::~SkBlurDrawLooper() { 65 SkSafeUnref(fBlur); 66 SkSafeUnref(fColorFilter); 67} 68 69void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) const { 70 this->INHERITED::flatten(buffer); 71 buffer.writeScalar(fDx); 72 buffer.writeScalar(fDy); 73 buffer.writeColor(fBlurColor); 74 buffer.writeFlattenable(fBlur); 75 buffer.writeFlattenable(fColorFilter); 76 buffer.writeUInt(fBlurFlags); 77} 78 79void SkBlurDrawLooper::init(SkCanvas* canvas) { 80 fState = kBeforeEdge; 81} 82 83bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 84 switch (fState) { 85 case kBeforeEdge: 86 // we do nothing if a maskfilter is already installed 87 if (paint->getMaskFilter()) { 88 fState = kDone; 89 return false; 90 } 91#ifdef SK_BUILD_FOR_ANDROID 92 SkColor blurColor; 93 blurColor = fBlurColor; 94 if (SkColorGetA(blurColor) == 255) { 95 blurColor = SkColorSetA(blurColor, paint->getAlpha()); 96 } 97 paint->setColor(blurColor); 98#else 99 paint->setColor(fBlurColor); 100#endif 101 paint->setMaskFilter(fBlur); 102 paint->setColorFilter(fColorFilter); 103 canvas->save(SkCanvas::kMatrix_SaveFlag); 104 if (fBlurFlags & kIgnoreTransform_BlurFlag) { 105 SkMatrix transform(canvas->getTotalMatrix()); 106 transform.postTranslate(fDx, fDy); 107 canvas->setMatrix(transform); 108 } else { 109 canvas->translate(fDx, fDy); 110 } 111 fState = kAfterEdge; 112 return true; 113 case kAfterEdge: 114 canvas->restore(); 115 fState = kDone; 116 return true; 117 default: 118 SkASSERT(kDone == fState); 119 return false; 120 } 121} 122