SkBlurDrawLooper.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkBlurDrawLooper.h"
9#include "SkBlurMaskFilter.h"
10#include "SkCanvas.h"
11#include "SkPaint.h"
12#include "SkMaskFilter.h"
13#include "SkColorFilter.h"
14
15SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
16                                   SkColor color, uint32_t flags)
17    : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
18
19    SkASSERT(flags <= kAll_BlurFlag);
20    if (radius > 0) {
21        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
22            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
23            SkBlurMaskFilter::kNone_BlurFlag;
24
25        blurFlags |= flags & kHighQuality_BlurFlag ?
26            SkBlurMaskFilter::kHighQuality_BlurFlag :
27            SkBlurMaskFilter::kNone_BlurFlag;
28
29        fBlur = SkBlurMaskFilter::Create(radius,
30                                         SkBlurMaskFilter::kNormal_BlurStyle,
31                                         blurFlags);
32    } else {
33        fBlur = NULL;
34    }
35
36    if (flags & kOverrideColor_BlurFlag) {
37        // Set alpha to 1 for the override since transparency will already
38        // be baked into the blurred mask.
39        SkColor opaqueColor = SkColorSetA(color, 255);
40        //The SrcIn xfer mode will multiply 'color' by the incoming alpha
41        fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
42                                                       SkXfermode::kSrcIn_Mode);
43    } else {
44        fColorFilter = NULL;
45    }
46}
47
48SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
49: INHERITED(buffer) {
50
51    fDx = buffer.readScalar();
52    fDy = buffer.readScalar();
53    fBlurColor = buffer.readU32();
54    fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
55    fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
56    fBlurFlags = buffer.readU32() & kAll_BlurFlag;
57}
58
59SkBlurDrawLooper::~SkBlurDrawLooper() {
60    SkSafeUnref(fBlur);
61    SkSafeUnref(fColorFilter);
62}
63
64void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
65    buffer.writeScalar(fDx);
66    buffer.writeScalar(fDy);
67    buffer.write32(fBlurColor);
68    buffer.writeFlattenable(fBlur);
69    buffer.writeFlattenable(fColorFilter);
70    buffer.write32(fBlurFlags);
71}
72
73void SkBlurDrawLooper::init(SkCanvas* canvas) {
74    fState = kBeforeEdge;
75}
76
77bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
78    switch (fState) {
79        case kBeforeEdge:
80            // we do nothing if a maskfilter is already installed
81            if (paint->getMaskFilter()) {
82                fState = kDone;
83                return false;
84            }
85#ifdef ANDROID
86            SkColor blurColor;
87            blurColor = fBlurColor;
88            if (SkColorGetA(blurColor) == 255) {
89                blurColor = SkColorSetA(blurColor, paint->getAlpha());
90            }
91            paint->setColor(blurColor);
92#else
93            paint->setColor(fBlurColor);
94#endif
95            paint->setMaskFilter(fBlur);
96            paint->setColorFilter(fColorFilter);
97            canvas->save(SkCanvas::kMatrix_SaveFlag);
98            if (fBlurFlags & kIgnoreTransform_BlurFlag) {
99                SkMatrix transform(canvas->getTotalMatrix());
100                transform.postTranslate(fDx, fDy);
101                canvas->setMatrix(transform);
102            } else {
103                canvas->translate(fDx, fDy);
104            }
105            fState = kAfterEdge;
106            return true;
107        case kAfterEdge:
108            canvas->restore();
109            fState = kDone;
110            return true;
111        default:
112            SkASSERT(kDone == fState);
113            return false;
114    }
115}
116
117///////////////////////////////////////////////////////////////////////////////
118
119static SkFlattenable::Registrar gReg("SkBlurDrawLooper",
120                                     SkBlurDrawLooper::CreateProc);
121
122