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 :
15 0 : SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
16 : SkColor color, uint32_t flags)
17 0 : : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
18 :
19 0 : SkASSERT(flags <= kAll_BlurFlag);
20 0 : if (radius > 0) {
21 : uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
22 : SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
23 0 : SkBlurMaskFilter::kNone_BlurFlag;
24 :
25 : blurFlags |= flags & kHighQuality_BlurFlag ?
26 : SkBlurMaskFilter::kHighQuality_BlurFlag :
27 0 : SkBlurMaskFilter::kNone_BlurFlag;
28 :
29 : fBlur = SkBlurMaskFilter::Create(radius,
30 : SkBlurMaskFilter::kNormal_BlurStyle,
31 0 : blurFlags);
32 : } else {
33 0 : fBlur = NULL;
34 : }
35 :
36 0 : if (flags & kOverrideColor_BlurFlag) {
37 : // Set alpha to 1 for the override since transparency will already
38 : // be baked into the blurred mask.
39 0 : SkColor opaqueColor = SkColorSetA(color, 255);
40 : //The SrcIn xfer mode will multiply 'color' by the incoming alpha
41 : fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
42 0 : SkXfermode::kSrcIn_Mode);
43 : } else {
44 0 : fColorFilter = NULL;
45 : }
46 0 : }
47 :
48 0 : SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
49 0 : : INHERITED(buffer) {
50 :
51 0 : fDx = buffer.readScalar();
52 0 : fDy = buffer.readScalar();
53 0 : fBlurColor = buffer.readU32();
54 0 : fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
55 0 : fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
56 0 : fBlurFlags = buffer.readU32() & kAll_BlurFlag;
57 0 : }
58 :
59 0 : SkBlurDrawLooper::~SkBlurDrawLooper() {
60 0 : SkSafeUnref(fBlur);
61 0 : SkSafeUnref(fColorFilter);
62 0 : }
63 :
64 0 : void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
65 0 : buffer.writeScalar(fDx);
66 0 : buffer.writeScalar(fDy);
67 0 : buffer.write32(fBlurColor);
68 0 : buffer.writeFlattenable(fBlur);
69 0 : buffer.writeFlattenable(fColorFilter);
70 0 : buffer.write32(fBlurFlags);
71 0 : }
72 :
73 0 : void SkBlurDrawLooper::init(SkCanvas* canvas) {
74 0 : fState = kBeforeEdge;
75 0 : }
76 :
77 0 : bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
78 0 : switch (fState) {
79 : case kBeforeEdge:
80 : // we do nothing if a maskfilter is already installed
81 0 : if (paint->getMaskFilter()) {
82 0 : fState = kDone;
83 0 : return false;
84 : }
85 : #ifdef SK_BUILD_FOR_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 0 : paint->setColor(fBlurColor);
94 : #endif
95 0 : paint->setMaskFilter(fBlur);
96 0 : paint->setColorFilter(fColorFilter);
97 0 : canvas->save(SkCanvas::kMatrix_SaveFlag);
98 0 : if (fBlurFlags & kIgnoreTransform_BlurFlag) {
99 0 : SkMatrix transform(canvas->getTotalMatrix());
100 0 : transform.postTranslate(fDx, fDy);
101 0 : canvas->setMatrix(transform);
102 : } else {
103 0 : canvas->translate(fDx, fDy);
104 : }
105 0 : fState = kAfterEdge;
106 0 : return true;
107 : case kAfterEdge:
108 0 : canvas->restore();
109 0 : fState = kDone;
110 0 : return true;
111 : default:
112 0 : SkASSERT(kDone == fState);
113 0 : return false;
114 : }
115 : }
116 :
117 : ///////////////////////////////////////////////////////////////////////////////
118 :
119 2928 : SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper)
120 :
|