blob: 9ec2aff97f4d1930eaee745e14a15937330b6e02 [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"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000011#include "SkFlattenableBuffers.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000012#include "SkPaint.h"
13#include "SkMaskFilter.h"
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000014#include "SkColorFilter.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015
16SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000017 SkColor color, uint32_t flags)
vandebo@chromium.orga728e352012-03-28 20:29:38 +000018 : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags), fState(kDone) {
reed@google.com4e2b3d32011-04-07 14:18:59 +000019
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000020 SkASSERT(flags <= kAll_BlurFlag);
reed@google.com4e2b3d32011-04-07 14:18:59 +000021 if (radius > 0) {
reed@google.com82065d62011-02-07 15:30:46 +000022 uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
23 SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000024 SkBlurMaskFilter::kNone_BlurFlag;
25
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000026 blurFlags |= flags & kHighQuality_BlurFlag ?
27 SkBlurMaskFilter::kHighQuality_BlurFlag :
28 SkBlurMaskFilter::kNone_BlurFlag;
29
reed@android.com8a1c16f2008-12-17 15:59:43 +000030 fBlur = SkBlurMaskFilter::Create(radius,
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000031 SkBlurMaskFilter::kNormal_BlurStyle,
senorblanco@chromium.org038aff62010-12-06 23:45:58 +000032 blurFlags);
reed@google.com4e2b3d32011-04-07 14:18:59 +000033 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 fBlur = NULL;
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000035 }
36
reed@google.com4e2b3d32011-04-07 14:18:59 +000037 if (flags & kOverrideColor_BlurFlag) {
junov@google.coma6398912011-03-11 16:45:00 +000038 // Set alpha to 1 for the override since transparency will already
39 // be baked into the blurred mask.
40 SkColor opaqueColor = SkColorSetA(color, 255);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000041 //The SrcIn xfer mode will multiply 'color' by the incoming alpha
reed@google.com4e2b3d32011-04-07 14:18:59 +000042 fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
43 SkXfermode::kSrcIn_Mode);
44 } else {
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000045 fColorFilter = NULL;
46 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000047}
48
reed@google.com6bac9472011-06-21 19:24:00 +000049SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
50: INHERITED(buffer) {
51
reed@android.com8a1c16f2008-12-17 15:59:43 +000052 fDx = buffer.readScalar();
53 fDy = buffer.readScalar();
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000054 fBlurColor = buffer.readColor();
55 fBlur = buffer.readFlattenableT<SkMaskFilter>();
56 fColorFilter = buffer.readFlattenableT<SkColorFilter>();
57 fBlurFlags = buffer.readUInt() & kAll_BlurFlag;
reed@android.com8a1c16f2008-12-17 15:59:43 +000058}
59
reed@google.com4e2b3d32011-04-07 14:18:59 +000060SkBlurDrawLooper::~SkBlurDrawLooper() {
reed@google.com82065d62011-02-07 15:30:46 +000061 SkSafeUnref(fBlur);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000062 SkSafeUnref(fColorFilter);
reed@android.com8a1c16f2008-12-17 15:59:43 +000063}
64
djsollen@google.com54924242012-03-29 15:18:04 +000065void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) const {
66 this->INHERITED::flatten(buffer);
reed@android.com8a1c16f2008-12-17 15:59:43 +000067 buffer.writeScalar(fDx);
68 buffer.writeScalar(fDy);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000069 buffer.writeColor(fBlurColor);
reed@android.com8a1c16f2008-12-17 15:59:43 +000070 buffer.writeFlattenable(fBlur);
senorblanco@chromium.org4868e6b2011-02-18 19:03:01 +000071 buffer.writeFlattenable(fColorFilter);
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000072 buffer.writeUInt(fBlurFlags);
reed@android.com8a1c16f2008-12-17 15:59:43 +000073}
74
reed@google.com4e2b3d32011-04-07 14:18:59 +000075void SkBlurDrawLooper::init(SkCanvas* canvas) {
76 fState = kBeforeEdge;
reed@android.com8a1c16f2008-12-17 15:59:43 +000077}
78
reed@google.com4e2b3d32011-04-07 14:18:59 +000079bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000080 switch (fState) {
reed@google.com4e2b3d32011-04-07 14:18:59 +000081 case kBeforeEdge:
82 // we do nothing if a maskfilter is already installed
83 if (paint->getMaskFilter()) {
84 fState = kDone;
85 return false;
86 }
djsollen@google.com56c69772011-11-08 19:00:26 +000087#ifdef SK_BUILD_FOR_ANDROID
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000088 SkColor blurColor;
89 blurColor = fBlurColor;
90 if (SkColorGetA(blurColor) == 255) {
91 blurColor = SkColorSetA(blurColor, paint->getAlpha());
92 }
93 paint->setColor(blurColor);
94#else
reed@google.com4e2b3d32011-04-07 14:18:59 +000095 paint->setColor(fBlurColor);
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000096#endif
reed@google.com4e2b3d32011-04-07 14:18:59 +000097 paint->setMaskFilter(fBlur);
98 paint->setColorFilter(fColorFilter);
99 canvas->save(SkCanvas::kMatrix_SaveFlag);
100 if (fBlurFlags & kIgnoreTransform_BlurFlag) {
101 SkMatrix transform(canvas->getTotalMatrix());
102 transform.postTranslate(fDx, fDy);
103 canvas->setMatrix(transform);
104 } else {
105 canvas->translate(fDx, fDy);
106 }
107 fState = kAfterEdge;
108 return true;
109 case kAfterEdge:
110 canvas->restore();
111 fState = kDone;
112 return true;
113 default:
114 SkASSERT(kDone == fState);
115 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116 }
117}
118
119///////////////////////////////////////////////////////////////////////////////
120
caryclark@google.comd26147a2011-12-15 14:16:43 +0000121SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122