10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/effects/SkBlurMaskFilter.cpp 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License. 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMaskFilter.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlurMask.h" 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h" 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkBlurMaskFilterImpl : public SkMaskFilter { 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 2540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, uint32_t flags); 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides from SkMaskFilter 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual SkMask::Format getFormat(); 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin); 30717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger virtual void computeFastBounds(const SkRect& src, SkRect* dst); 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides from SkFlattenable 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // This method is not exported to java. 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory(); 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // This method is not exported to java. 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void flatten(SkFlattenableWriteBuffer&); 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fRadius; 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilter::BlurStyle fBlurStyle; 4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t fBlurFlags; 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkMaskFilter INHERITED; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t flags) 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount 5440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger || flags > SkBlurMaskFilter::kAll_BlurFlag) 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////////////////////// 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 6340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t flags) 6440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = NULL; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (gammaScale) 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = new U8[256]; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (gammaScale > 0) 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrGamma(fGamma, gammaScale); 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(radius >= 0); 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMask::Format SkBlurMaskFilterImpl::getFormat() 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkMask::kA8_Format; 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin) 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar radius; 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = fRadius; 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger else 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = matrix.mapRadius(fRadius); 9440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 95af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // To avoid unseemly allocation requests (esp. for finite platforms like 96af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // handset) we limit the radius so something manageable. (as opposed to 97af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // a request like 10,000) 98af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project static const SkScalar MAX_RADIUS = SkIntToScalar(128); 99af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project radius = SkMinScalar(radius, MAX_RADIUS); 10071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMask::Quality blurQuality = (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 10171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10371531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger if (SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, blurQuality)) 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 105af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project if (margin) { 106af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // we need to integralize radius for our margin, so take the ceil 107af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // just to be safe. 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project margin->set(SkScalarCeil(radius), SkScalarCeil(radius)); 109af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project } 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 113717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 114717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 115717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) { 116717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger dst->set(src.fLeft - fRadius, src.fTop - fRadius, 117717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger src.fRight + fRadius, src.fBottom + fRadius); 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer) 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer)); 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkBlurMaskFilterImpl::getFactory() 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer) 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRadius = buffer.readScalar(); 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32(); 13440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag; 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRadius >= 0); 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(buffer); 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fRadius); 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurStyle); 14440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurMaskFilter", 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilterImpl::CreateProc); 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 152