SkBlurDrawLooper.cpp revision 038aff623d9fd47946cd31685f74cf473f7c84f0
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurDrawLooper.h"
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurMaskFilter.h"
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h"
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
8038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org                                   SkColor color, uint32_t flags)
9038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags)
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
11038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    SkASSERT(flags <= kAll_BlurFlag);
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (radius > 0)
13038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    {
14038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
15038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
16038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            SkBlurMaskFilter::kNone_BlurFlag;
17038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBlur = SkBlurMaskFilter::Create(radius,
19038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org                                         SkBlurMaskFilter::kNormal_BlurStyle,
20038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org                                         blurFlags);
21038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    }
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBlur = NULL;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fDx = buffer.readScalar();
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fDy = buffer.readScalar();
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBlurColor = buffer.readU32();
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
32038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    fBlurFlags = buffer.readU32() & kAll_BlurFlag;
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBlurDrawLooper::~SkBlurDrawLooper()
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBlur->safeUnref();
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeScalar(fDx);
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeScalar(fDy);
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.write32(fBlurColor);
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeFlattenable(fBlur);
46038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org    buffer.write32(fBlurFlags);
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // we do nothing if a maskfilter is already installed
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (paint->getMaskFilter() != NULL)
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fState = kDone;
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fState = kBeforeEdge;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint = paint;
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCanvas = canvas;
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fSaveCount = canvas->getSaveCount();
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBlurDrawLooper::next()
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (fState) {
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case kBeforeEdge:
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fSavedColor = fPaint->getColor();
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setColor(fBlurColor);
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setMaskFilter(fBlur);
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCanvas->save(SkCanvas::kMatrix_SaveFlag);
71038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        if (fBlurFlags & kIgnoreTransform_BlurFlag)
72038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        {
73038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            SkMatrix transform(fCanvas->getTotalMatrix());
74038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            transform.postTranslate(fDx, fDy);
75038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            fCanvas->setMatrix(transform);
76038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        }
77038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        else
78038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        {
79038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org            fCanvas->translate(fDx, fDy);
80038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org        }
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fState = kAfterEdge;
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case kAfterEdge:
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setColor(fSavedColor);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setMaskFilter(NULL);
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCanvas->restore(); // to remove the translate we did earlier
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fState = kDone;
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    default:
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(kDone == fState);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false;
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlurDrawLooper::restore()
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (kAfterEdge == fState)
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setColor(fSavedColor);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPaint->setMaskFilter(NULL);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCanvas->restore(); // to remove the translate we did earlier
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fState = kDone;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper",
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                     SkBlurDrawLooper::CreateProc);
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
111