SkBlurDrawLooper.cpp revision 4868e6b221a4a98e40f977851af5fcf09631ea15
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
8SkBlurDrawLooper::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    {
15        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
16            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
17            SkBlurMaskFilter::kNone_BlurFlag;
18
19        blurFlags |= flags & kHighQuality_BlurFlag ?
20            SkBlurMaskFilter::kHighQuality_BlurFlag :
21            SkBlurMaskFilter::kNone_BlurFlag;
22
23        fBlur = SkBlurMaskFilter::Create(radius,
24                                         SkBlurMaskFilter::kNormal_BlurStyle,
25                                         blurFlags);
26    }
27    else
28    {
29        fBlur = NULL;
30    }
31
32    if (flags & kOverrideColor_BlurFlag)
33    {
34        //The SrcIn xfer mode will multiply 'color' by the incoming alpha
35        fColorFilter = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode);
36    }
37    else
38    {
39        fColorFilter = NULL;
40    }
41}
42
43SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
44{
45    fDx = buffer.readScalar();
46    fDy = buffer.readScalar();
47    fBlurColor = buffer.readU32();
48    fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
49    fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
50    fBlurFlags = buffer.readU32() & kAll_BlurFlag;
51}
52
53SkBlurDrawLooper::~SkBlurDrawLooper()
54{
55    SkSafeUnref(fBlur);
56    SkSafeUnref(fColorFilter);
57}
58
59void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
60{
61    buffer.writeScalar(fDx);
62    buffer.writeScalar(fDy);
63    buffer.write32(fBlurColor);
64    buffer.writeFlattenable(fBlur);
65    buffer.writeFlattenable(fColorFilter);
66    buffer.write32(fBlurFlags);
67}
68
69void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
70{
71    // we do nothing if a maskfilter is already installed
72    if (paint->getMaskFilter() != NULL)
73        fState = kDone;
74    else
75    {
76        fState = kBeforeEdge;
77        fPaint = paint;
78        fCanvas = canvas;
79        fSaveCount = canvas->getSaveCount();
80    }
81}
82
83bool SkBlurDrawLooper::next()
84{
85    switch (fState) {
86    case kBeforeEdge:
87        fSavedColor = fPaint->getColor();
88        fPaint->setColor(fBlurColor);
89        fPaint->setMaskFilter(fBlur);
90        fPaint->setColorFilter(fColorFilter);
91        fCanvas->save(SkCanvas::kMatrix_SaveFlag);
92        if (fBlurFlags & kIgnoreTransform_BlurFlag)
93        {
94            SkMatrix transform(fCanvas->getTotalMatrix());
95            transform.postTranslate(fDx, fDy);
96            fCanvas->setMatrix(transform);
97        }
98        else
99        {
100            fCanvas->translate(fDx, fDy);
101        }
102        fState = kAfterEdge;
103        return true;
104    case kAfterEdge:
105        fPaint->setColor(fSavedColor);
106        fPaint->setMaskFilter(NULL);
107        fPaint->setColorFilter(NULL);
108        fCanvas->restore(); // to remove the translate we did earlier
109        fState = kDone;
110        return true;
111    default:
112        SkASSERT(kDone == fState);
113        return false;
114    }
115}
116
117void SkBlurDrawLooper::restore()
118{
119    if (kAfterEdge == fState)
120    {
121        fPaint->setColor(fSavedColor);
122        fPaint->setMaskFilter(NULL);
123        fPaint->setColorFilter(NULL);
124        fCanvas->restore(); // to remove the translate we did earlier
125        fState = kDone;
126    }
127}
128
129///////////////////////////////////////////////////////////////////////////////
130
131static SkFlattenable::Registrar gReg("SkBlurDrawLooper",
132                                     SkBlurDrawLooper::CreateProc);
133
134