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
SkBlurDrawLooper(SkScalar radius,SkScalar dx,SkScalar dy,SkColor color,uint32_t flags)15 SkBlurDrawLooper::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
SkBlurDrawLooper(SkFlattenableReadBuffer & buffer)48 SkBlurDrawLooper::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
~SkBlurDrawLooper()59 SkBlurDrawLooper::~SkBlurDrawLooper() {
60 SkSafeUnref(fBlur);
61 SkSafeUnref(fColorFilter);
62 }
63
flatten(SkFlattenableWriteBuffer & buffer)64 void 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
init(SkCanvas * canvas)73 void SkBlurDrawLooper::init(SkCanvas* canvas) {
74 fState = kBeforeEdge;
75 }
76
next(SkCanvas * canvas,SkPaint * paint)77 bool 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 SK_BUILD_FOR_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
119 SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper)
120
121