blob: 656f8f7d6cd6707a5adabe9a831e55443b143940 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkBlurDrawLooper.h"
9#include "SkBlurMaskFilter.h"
10#include "SkCanvas.h"
11#include "SkPaint.h"
12#include "SkMaskFilter.h"
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000013#include "SkColorFilter.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000014
15SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000016 SkColor color, uint32_t flags)
vandebo@chromium.orga728e352012-03-28 20:29:38 +000017 : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags), fState(kDone) {
reed@google.com4e2b3d32011-04-07 14:18:59 +000018
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000019 SkASSERT(flags <= kAll_BlurFlag);
reed@google.com4e2b3d32011-04-07 14:18:59 +000020 if (radius > 0) {
reed@google.com82065d62011-02-07 15:30:46 +000021 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
22 SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000023 SkBlurMaskFilter::kNone_BlurFlag;
24
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000025 blurFlags |= flags & kHighQuality_BlurFlag ?
26 SkBlurMaskFilter::kHighQuality_BlurFlag :
27 SkBlurMaskFilter::kNone_BlurFlag;
28
reed@android.com8a1c16f2008-12-17 15:59:43 +000029 fBlur = SkBlurMaskFilter::Create(radius,
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000030 SkBlurMaskFilter::kNormal_BlurStyle,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000031 blurFlags);
reed@google.com4e2b3d32011-04-07 14:18:59 +000032 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +000033 fBlur = NULL;
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000034 }
35
reed@google.com4e2b3d32011-04-07 14:18:59 +000036 if (flags & kOverrideColor_BlurFlag) {
junov@google.coma6398912011-03-11 16:45:00 +000037 // Set alpha to 1 for the override since transparency will already
38 // be baked into the blurred mask.
39 SkColor opaqueColor = SkColorSetA(color, 255);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000040 //The SrcIn xfer mode will multiply 'color' by the incoming alpha
reed@google.com4e2b3d32011-04-07 14:18:59 +000041 fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
42 SkXfermode::kSrcIn_Mode);
43 } else {
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000044 fColorFilter = NULL;
45 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000046}
47
reed@google.com6bac9472011-06-21 19:24:00 +000048SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
49: INHERITED(buffer) {
50
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 fDx = buffer.readScalar();
52 fDy = buffer.readScalar();
53 fBlurColor = buffer.readU32();
54 fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000055 fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000056 fBlurFlags = buffer.readU32() & kAll_BlurFlag;
reed@android.com8a1c16f2008-12-17 15:59:43 +000057}
58
reed@google.com4e2b3d32011-04-07 14:18:59 +000059SkBlurDrawLooper::~SkBlurDrawLooper() {
reed@google.com82065d62011-02-07 15:30:46 +000060 SkSafeUnref(fBlur);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000061 SkSafeUnref(fColorFilter);
reed@android.com8a1c16f2008-12-17 15:59:43 +000062}
63
reed@google.com4e2b3d32011-04-07 14:18:59 +000064void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000065 buffer.writeScalar(fDx);
66 buffer.writeScalar(fDy);
67 buffer.write32(fBlurColor);
68 buffer.writeFlattenable(fBlur);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000069 buffer.writeFlattenable(fColorFilter);
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000070 buffer.write32(fBlurFlags);
reed@android.com8a1c16f2008-12-17 15:59:43 +000071}
72
reed@google.com4e2b3d32011-04-07 14:18:59 +000073void SkBlurDrawLooper::init(SkCanvas* canvas) {
74 fState = kBeforeEdge;
reed@android.com8a1c16f2008-12-17 15:59:43 +000075}
76
reed@google.com4e2b3d32011-04-07 14:18:59 +000077bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000078 switch (fState) {
reed@google.com4e2b3d32011-04-07 14:18:59 +000079 case kBeforeEdge:
80 // we do nothing if a maskfilter is already installed
81 if (paint->getMaskFilter()) {
82 fState = kDone;
83 return false;
84 }
djsollen@google.com56c69772011-11-08 19:00:26 +000085#ifdef SK_BUILD_FOR_ANDROID
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000086 SkColor blurColor;
87 blurColor = fBlurColor;
88 if (SkColorGetA(blurColor) == 255) {
89 blurColor = SkColorSetA(blurColor, paint->getAlpha());
90 }
91 paint->setColor(blurColor);
92#else
reed@google.com4e2b3d32011-04-07 14:18:59 +000093 paint->setColor(fBlurColor);
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000094#endif
reed@google.com4e2b3d32011-04-07 14:18:59 +000095 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;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 }
115}
116
117///////////////////////////////////////////////////////////////////////////////
118
caryclark@google.comd26147a2011-12-15 14:16:43 +0000119SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000120