• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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