SkBlurDrawLooper.cpp revision 87b8e645865f9633f410c02252a0fd3feb18f09b
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurDrawLooper.h"
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMaskFilter.h"
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCanvas.h"
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger#include "SkColorFilter.h"
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                   SkColor color, uint32_t flags)
1087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
1187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkASSERT(flags <= kAll_BlurFlag);
1387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (radius > 0) {
1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SkBlurMaskFilter::kNone_BlurFlag;
1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger        blurFlags |= flags & kHighQuality_BlurFlag ?
1971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger            SkBlurMaskFilter::kHighQuality_BlurFlag :
2071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger            SkBlurMaskFilter::kNone_BlurFlag;
2171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlur = SkBlurMaskFilter::Create(radius,
2371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger                                         SkBlurMaskFilter::kNormal_BlurStyle,
2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                         blurFlags);
2587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlur = NULL;
2771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger    }
2871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger
2987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (flags & kOverrideColor_BlurFlag) {
30137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        // Set alpha to 1 for the override since transparency will already
31137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        // be baked into the blurred mask.
32137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        SkColor opaqueColor = SkColorSetA(color, 255);
3371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger        //The SrcIn xfer mode will multiply 'color' by the incoming alpha
3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                                                       SkXfermode::kSrcIn_Mode);
3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger        fColorFilter = NULL;
3871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger    }
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) {
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDx = buffer.readScalar();
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDy = buffer.readScalar();
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlurColor = buffer.readU32();
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
4671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger    fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fBlurFlags = buffer.readU32() & kAll_BlurFlag;
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5087b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkBlurDrawLooper::~SkBlurDrawLooper() {
5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fBlur);
5271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger    SkSafeUnref(fColorFilter);
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(fDx);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(fDy);
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fBlurColor);
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(fBlur);
6071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger    buffer.writeFlattenable(fColorFilter);
6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    buffer.write32(fBlurFlags);
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::init(SkCanvas* canvas) {
6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fState = kBeforeEdge;
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (fState) {
7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        case kBeforeEdge:
7187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            // we do nothing if a maskfilter is already installed
7287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            if (paint->getMaskFilter()) {
7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                fState = kDone;
7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                return false;
7587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            }
7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#ifdef ANDROID
7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            SkColor blurColor;
7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            blurColor = fBlurColor;
7987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            if (SkColorGetA(blurColor) == 255) {
8087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                blurColor = SkColorSetA(blurColor, paint->getAlpha());
8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            }
8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            paint->setColor(blurColor);
8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else
8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            paint->setColor(fBlurColor);
8587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
8687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            paint->setMaskFilter(fBlur);
8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            paint->setColorFilter(fColorFilter);
8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            canvas->save(SkCanvas::kMatrix_SaveFlag);
8987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            if (fBlurFlags & kIgnoreTransform_BlurFlag) {
9087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                SkMatrix transform(canvas->getTotalMatrix());
9187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                transform.postTranslate(fDx, fDy);
9287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                canvas->setMatrix(transform);
9387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            } else {
9487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                canvas->translate(fDx, fDy);
9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            }
9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            fState = kAfterEdge;
9787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            return true;
9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        case kAfterEdge:
9987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            canvas->restore();
10087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            fState = kDone;
10187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            return true;
10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        default:
10387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            SkASSERT(kDone == fState);
10487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            return false;
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurDrawLooper",
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                     SkBlurDrawLooper::CreateProc);
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
113