11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurDrawLooper.h" 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMaskFilter.h" 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCanvas.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 1371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger#include "SkColorFilter.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkColor color, uint32_t flags) 1787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) { 1887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 1940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= kAll_BlurFlag); 2087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (radius > 0) { 2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? 2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kIgnoreTransform_BlurFlag : 2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger blurFlags |= flags & kHighQuality_BlurFlag ? 2671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kHighQuality_BlurFlag : 2771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNone_BlurFlag; 2871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = SkBlurMaskFilter::Create(radius, 3071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMaskFilter::kNormal_BlurStyle, 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger blurFlags); 3287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = NULL; 3471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 3571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (flags & kOverrideColor_BlurFlag) { 37137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // Set alpha to 1 for the override since transparency will already 38137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // be baked into the blurred mask. 39137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger SkColor opaqueColor = SkColorSetA(color, 255); 4071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger //The SrcIn xfer mode will multiply 'color' by the incoming alpha 4187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, 4287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkXfermode::kSrcIn_Mode); 4387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 4471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = NULL; 4571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger } 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 481cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger: INHERITED(buffer) { 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDx = buffer.readScalar(); 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDy = buffer.readScalar(); 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurColor = buffer.readU32(); 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable()); 5571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger fColorFilter = static_cast<SkColorFilter*>(buffer.readFlattenable()); 5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & kAll_BlurFlag; 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5987b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkBlurDrawLooper::~SkBlurDrawLooper() { 6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fBlur); 6171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkSafeUnref(fColorFilter); 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDx); 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fDy); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurColor); 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFlattenable(fBlur); 6971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger buffer.writeFlattenable(fColorFilter); 7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkBlurDrawLooper::init(SkCanvas* canvas) { 7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kBeforeEdge; 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (fState) { 7987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger case kBeforeEdge: 8087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger // we do nothing if a maskfilter is already installed 8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (paint->getMaskFilter()) { 8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kDone; 8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return false; 8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 8687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkColor blurColor; 8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger blurColor = fBlurColor; 8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (SkColorGetA(blurColor) == 255) { 8987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger blurColor = SkColorSetA(blurColor, paint->getAlpha()); 9087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 9187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColor(blurColor); 9287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else 9387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColor(fBlurColor); 9487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setMaskFilter(fBlur); 9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger paint->setColorFilter(fColorFilter); 9787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->save(SkCanvas::kMatrix_SaveFlag); 9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (fBlurFlags & kIgnoreTransform_BlurFlag) { 9987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkMatrix transform(canvas->getTotalMatrix()); 10087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger transform.postTranslate(fDx, fDy); 10187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->setMatrix(transform); 10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 10387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->translate(fDx, fDy); 10487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 10587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kAfterEdge; 10687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return true; 10787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger case kAfterEdge: 10887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger canvas->restore(); 10987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fState = kDone; 11087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return true; 11187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger default: 11287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkASSERT(kDone == fState); 11387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return false; 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1191cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper) 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 121