1 /* libs/graphics/effects/SkBlurMaskFilter.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "SkBlurMaskFilter.h" 19 #include "SkBlurMask.h" 20 #include "SkBuffer.h" 21 #include "SkMaskFilter.h" 22 23 class SkBlurMaskFilterImpl : public SkMaskFilter { 24 public: 25 SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, uint32_t flags); 26 27 // overrides from SkMaskFilter 28 virtual SkMask::Format getFormat(); 29 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin); 30 virtual void computeFastBounds(const SkRect& src, SkRect* dst); 31 32 // overrides from SkFlattenable 33 // This method is not exported to java. 34 virtual Factory getFactory(); 35 // This method is not exported to java. 36 virtual void flatten(SkFlattenableWriteBuffer&); 37 38 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); 39 40 private: 41 SkScalar fRadius; 42 SkBlurMaskFilter::BlurStyle fBlurStyle; 43 uint32_t fBlurFlags; 44 45 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); 46 47 typedef SkMaskFilter INHERITED; 48 }; 49 50 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 51 uint32_t flags) 52 { 53 if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount 54 || flags > SkBlurMaskFilter::kAll_BlurFlag) 55 return NULL; 56 57 return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); 58 } 59 60 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 61 62 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, 63 uint32_t flags) 64 : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) 65 { 66 #if 0 67 fGamma = NULL; 68 if (gammaScale) 69 { 70 fGamma = new U8[256]; 71 if (gammaScale > 0) 72 SkBlurMask::BuildSqrGamma(fGamma, gammaScale); 73 else 74 SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); 75 } 76 #endif 77 SkASSERT(radius >= 0); 78 SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); 79 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 80 } 81 82 SkMask::Format SkBlurMaskFilterImpl::getFormat() 83 { 84 return SkMask::kA8_Format; 85 } 86 87 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin) 88 { 89 SkScalar radius; 90 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) 91 radius = fRadius; 92 else 93 radius = matrix.mapRadius(fRadius); 94 95 // To avoid unseemly allocation requests (esp. for finite platforms like 96 // handset) we limit the radius so something manageable. (as opposed to 97 // a request like 10,000) 98 static const SkScalar MAX_RADIUS = SkIntToScalar(128); 99 radius = SkMinScalar(radius, MAX_RADIUS); 100 SkBlurMask::Quality blurQuality = (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 101 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; 102 103 if (SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, blurQuality)) 104 { 105 if (margin) { 106 // we need to integralize radius for our margin, so take the ceil 107 // just to be safe. 108 margin->set(SkScalarCeil(radius), SkScalarCeil(radius)); 109 } 110 return true; 111 } 112 return false; 113 } 114 115 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) { 116 dst->set(src.fLeft - fRadius, src.fTop - fRadius, 117 src.fRight + fRadius, src.fBottom + fRadius); 118 } 119 120 SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer) 121 { 122 return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer)); 123 } 124 125 SkFlattenable::Factory SkBlurMaskFilterImpl::getFactory() 126 { 127 return CreateProc; 128 } 129 130 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer) 131 { 132 fRadius = buffer.readScalar(); 133 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32(); 134 fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag; 135 SkASSERT(fRadius >= 0); 136 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); 137 } 138 139 void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) 140 { 141 this->INHERITED::flatten(buffer); 142 buffer.writeScalar(fRadius); 143 buffer.write32(fBlurStyle); 144 buffer.write32(fBlurFlags); 145 } 146 147 /////////////////////////////////////////////////////////////////////////////// 148 149 static SkFlattenable::Registrar gReg("SkBlurMaskFilter", 150 SkBlurMaskFilterImpl::CreateProc); 151 152