SkBlurMaskFilter.cpp revision 71531ca1f484da5837be8017a0c83e5bff701587
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); 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // overrides from SkFlattenable 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // This method is not exported to java. 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory(); 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // This method is not exported to java. 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void flatten(SkFlattenableWriteBuffer&); 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fRadius; 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilter::BlurStyle fBlurStyle; 4240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t fBlurFlags; 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkMaskFilter INHERITED; 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t flags) 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger || flags > SkBlurMaskFilter::kAll_BlurFlag) 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////////////////////// 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t flags) 6340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = NULL; 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (gammaScale) 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGamma = new U8[256]; 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (gammaScale > 0) 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrGamma(fGamma, gammaScale); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(radius >= 0); 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMask::Format SkBlurMaskFilterImpl::getFormat() 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkMask::kA8_Format; 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin) 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar radius; 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = fRadius; 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger else 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger radius = matrix.mapRadius(fRadius); 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 94af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // To avoid unseemly allocation requests (esp. for finite platforms like 95af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // handset) we limit the radius so something manageable. (as opposed to 96af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // a request like 10,000) 97af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project static const SkScalar MAX_RADIUS = SkIntToScalar(128); 98af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project radius = SkMinScalar(radius, MAX_RADIUS); 9971531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMask::Quality blurQuality = (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 10071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger if (SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, blurQuality)) 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 104af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project if (margin) { 105af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // we need to integralize radius for our margin, so take the ceil 106af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project // just to be safe. 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project margin->set(SkScalarCeil(radius), SkScalarCeil(radius)); 108af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project } 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer) 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer)); 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkBlurMaskFilterImpl::getFactory() 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer) 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRadius = buffer.readScalar(); 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32(); 12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag; 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRadius >= 0); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(buffer); 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeScalar(fRadius); 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fBlurStyle); 13840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger buffer.write32(fBlurFlags); 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurMaskFilter", 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlurMaskFilterImpl::CreateProc); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 146