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
SkBlurDrawLooper(SkScalar radius,SkScalar dx,SkScalar dy,SkColor color,uint32_t flags)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
SkBlurDrawLooper(SkFlattenableReadBuffer & buffer)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
~SkBlurDrawLooper()50 SkBlurDrawLooper::~SkBlurDrawLooper() {
51 SkSafeUnref(fBlur);
52 SkSafeUnref(fColorFilter);
53 }
54
flatten(SkFlattenableWriteBuffer & buffer)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
init(SkCanvas * canvas)64 void SkBlurDrawLooper::init(SkCanvas* canvas) {
65 fState = kBeforeEdge;
66 }
67
next(SkCanvas * canvas,SkPaint * paint)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