SkBlurDrawLooper.cpp revision f5dbe2f00f853c6a1719924bdd0c33335a53423a
19a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "SkBlurDrawLooper.h"
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "SkBlurMaskFilter.h"
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "SkCanvas.h"
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "SkPaint.h"
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "SkMaskFilter.h"
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "SkColorFilter.h"
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                   SkColor color, uint32_t flags)
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    SkASSERT(flags <= kAll_BlurFlag);
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (radius > 0) {
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com            SkBlurMaskFilter::kNone_BlurFlag;
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        blurFlags |= flags & kHighQuality_BlurFlag ?
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            SkBlurMaskFilter::kHighQuality_BlurFlag :
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            SkBlurMaskFilter::kNone_BlurFlag;
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        fBlur = SkBlurMaskFilter::Create(radius,
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                         SkBlurMaskFilter::kNormal_BlurStyle,
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                         blurFlags);
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    } else {
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        fBlur = NULL;
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (flags & kOverrideColor_BlurFlag) {
309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // Set alpha to 1 for the override since transparency will already
319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // be baked into the blurred mask.
329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        SkColor opaqueColor = SkColorSetA(color, 255);
33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        //The SrcIn xfer mode will multiply 'color' by the incoming alpha
34b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
35f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                                       SkXfermode::kSrcIn_Mode);
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        fColorFilter = NULL;
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
405ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
415ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) {
42763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    fDx = buffer.readScalar();
4318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    fDy = buffer.readScalar();
44763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    fBlurColor = buffer.readU32();
45763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
46196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
474b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    fBlurFlags = buffer.readU32() & kAll_BlurFlag;
48196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgSkBlurDrawLooper::~SkBlurDrawLooper() {
5171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    SkSafeUnref(fBlur);
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    SkSafeUnref(fColorFilter);
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.writeScalar(fDx);
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.writeScalar(fDy);
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.write32(fBlurColor);
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.writeFlattenable(fBlur);
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.writeFlattenable(fColorFilter);
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    buffer.write32(fBlurFlags);
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid SkBlurDrawLooper::init(SkCanvas* canvas) {
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    fState = kBeforeEdge;
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    switch (fState) {
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        case kBeforeEdge:
7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            // we do nothing if a maskfilter is already installed
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (paint->getMaskFilter()) {
735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org                fState = kDone;
74c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                return false;
75c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            }
76c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org#ifdef ANDROID
77c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            SkColor blurColor;
78c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            blurColor = fBlurColor;
79c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            if (SkColorGetA(blurColor) == 255) {
80c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                blurColor = SkColorSetA(blurColor, paint->getAlpha());
81c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            }
82c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            paint->setColor(blurColor);
83c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org#else
84c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            paint->setColor(fBlurColor);
85c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org#endif
86c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            paint->setMaskFilter(fBlur);
87c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            paint->setColorFilter(fColorFilter);
88c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            canvas->save(SkCanvas::kMatrix_SaveFlag);
89c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            if (fBlurFlags & kIgnoreTransform_BlurFlag) {
90c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                SkMatrix transform(canvas->getTotalMatrix());
91c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                transform.postTranslate(fDx, fDy);
92c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org                canvas->setMatrix(transform);
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            } else {
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                canvas->translate(fDx, fDy);
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            }
963d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org            fState = kAfterEdge;
97c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            return true;
983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        case kAfterEdge:
99a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            canvas->restore();
100a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            fState = kDone;
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            return true;
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        default:
103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            SkASSERT(kDone == fState);
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            return false;
105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
108e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org///////////////////////////////////////////////////////////////////////////////
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper",
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                     SkBlurDrawLooper::CreateProc);
112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
113e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org