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