blob: a3c4eacb6f1e7eba084c476030fc092e5b53f69b [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SkBlurDrawLooper.h"
2#include "SkBlurMaskFilter.h"
3#include "SkCanvas.h"
4#include "SkPaint.h"
5#include "SkMaskFilter.h"
6
7SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +00008 SkColor color, uint32_t flags)
9 : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags)
reed@android.com8a1c16f2008-12-17 15:59:43 +000010{
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000011 SkASSERT(flags <= kAll_BlurFlag);
reed@android.com8a1c16f2008-12-17 15:59:43 +000012 if (radius > 0)
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000013 {
reed@google.com82065d62011-02-07 15:30:46 +000014 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
15 SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000016 SkBlurMaskFilter::kNone_BlurFlag;
17
reed@android.com8a1c16f2008-12-17 15:59:43 +000018 fBlur = SkBlurMaskFilter::Create(radius,
reed@google.com82065d62011-02-07 15:30:46 +000019 SkBlurMaskFilter::kNormal_BlurStyle,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000020 blurFlags);
21 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000022 else
23 fBlur = NULL;
24}
25
26SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
27{
28 fDx = buffer.readScalar();
29 fDy = buffer.readScalar();
30 fBlurColor = buffer.readU32();
31 fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000032 fBlurFlags = buffer.readU32() & kAll_BlurFlag;
reed@android.com8a1c16f2008-12-17 15:59:43 +000033}
34
35SkBlurDrawLooper::~SkBlurDrawLooper()
36{
reed@google.com82065d62011-02-07 15:30:46 +000037 SkSafeUnref(fBlur);
reed@android.com8a1c16f2008-12-17 15:59:43 +000038}
39
40void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
41{
42 buffer.writeScalar(fDx);
43 buffer.writeScalar(fDy);
44 buffer.write32(fBlurColor);
45 buffer.writeFlattenable(fBlur);
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000046 buffer.write32(fBlurFlags);
reed@android.com8a1c16f2008-12-17 15:59:43 +000047}
48
49void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
50{
51 // we do nothing if a maskfilter is already installed
52 if (paint->getMaskFilter() != NULL)
53 fState = kDone;
54 else
55 {
56 fState = kBeforeEdge;
57 fPaint = paint;
58 fCanvas = canvas;
59 fSaveCount = canvas->getSaveCount();
60 }
61}
62
63bool SkBlurDrawLooper::next()
64{
65 switch (fState) {
66 case kBeforeEdge:
67 fSavedColor = fPaint->getColor();
68 fPaint->setColor(fBlurColor);
69 fPaint->setMaskFilter(fBlur);
70 fCanvas->save(SkCanvas::kMatrix_SaveFlag);
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000071 if (fBlurFlags & kIgnoreTransform_BlurFlag)
72 {
73 SkMatrix transform(fCanvas->getTotalMatrix());
74 transform.postTranslate(fDx, fDy);
75 fCanvas->setMatrix(transform);
76 }
77 else
78 {
79 fCanvas->translate(fDx, fDy);
80 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000081 fState = kAfterEdge;
82 return true;
83 case kAfterEdge:
84 fPaint->setColor(fSavedColor);
85 fPaint->setMaskFilter(NULL);
86 fCanvas->restore(); // to remove the translate we did earlier
87 fState = kDone;
88 return true;
89 default:
90 SkASSERT(kDone == fState);
91 return false;
92 }
93}
94
95void SkBlurDrawLooper::restore()
96{
97 if (kAfterEdge == fState)
98 {
99 fPaint->setColor(fSavedColor);
100 fPaint->setMaskFilter(NULL);
101 fCanvas->restore(); // to remove the translate we did earlier
102 fState = kDone;
103 }
104}
105
106///////////////////////////////////////////////////////////////////////////////
107
108static SkFlattenable::Registrar gReg("SkBlurDrawLooper",
109 SkBlurDrawLooper::CreateProc);
110