11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 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 */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMaskFilter.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMask.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkBlurMaskFilterImpl : public SkMaskFilter { 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle, 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags); 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides from SkMaskFilter 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual SkMask::Format getFormat() SK_OVERRIDE; 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIPoint* margin) SK_OVERRIDE; 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual BlurType asABlur(BlurInfo*) const SK_OVERRIDE; 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void computeFastBounds(const SkRect& src, SkRect* dst) SK_OVERRIDE; 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides from SkFlattenable 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE; 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE; 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fRadius; 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilter::BlurStyle fBlurStyle; 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t fBlurFlags; 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkMaskFilter INHERITED; 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 431cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBlurMaskFilter::BlurStyle style, 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags) { 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // use !(radius > 0) instead of radius <= 0 to reject NaN values 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || flags > SkBlurMaskFilter::kAll_BlurFlag) { 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 571cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBlurMaskFilter::BlurStyle style, 5940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t flags) 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) { 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = NULL; 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (gammaScale) { 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = new U8[256]; 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (gammaScale > 0) 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrGamma(fGamma, gammaScale); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(radius >= 0); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 761cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMask::Format SkBlurMaskFilterImpl::getFormat() { 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkMask::kA8_Format; 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMatrix& matrix, SkIPoint* margin) { 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar radius; 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = fRadius; 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = matrix.mapRadius(fRadius); 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 89af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // To avoid unseemly allocation requests (esp. for finite platforms like 90af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // handset) we limit the radius so something manageable. (as opposed to 91af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // a request like 10,000) 92af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project static const SkScalar MAX_RADIUS = SkIntToScalar(128); 93af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project radius = SkMinScalar(radius, MAX_RADIUS); 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBlurMask::Quality blurQuality = 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger blurQuality, margin); 100717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 101717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 102717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) { 103717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger dst->set(src.fLeft - fRadius, src.fTop - fRadius, 104717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger src.fRight + fRadius, src.fBottom + fRadius); 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1071cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer) { 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer)); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1111cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable::Factory SkBlurMaskFilterImpl::getFactory() { 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1151cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger : SkMaskFilter(buffer) { 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRadius = buffer.readScalar(); 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32(); 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag; 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRadius >= 0); 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) { 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(buffer); 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fRadius); 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurStyle); 12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const SkMaskFilter::BlurType gBlurStyle2BlurType[] = { 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMaskFilter::kNormal_BlurType, 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMaskFilter::kSolid_BlurType, 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMaskFilter::kOuter_BlurType, 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMaskFilter::kInner_BlurType, 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1381cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMaskFilter::BlurType SkBlurMaskFilterImpl::asABlur(BlurInfo* info) const { 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (info) { 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger info->fRadius = fRadius; 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger info->fIgnoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag); 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger info->fHighQuality = SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag); 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return gBlurStyle2BlurType[fBlurStyle]; 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1471cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1491cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 150