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);
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
31 // overrides from SkFlattenable
32 // This method is not exported to java.
33 virtual Factory getFactory();
34 // This method is not exported to java.
35 virtual void flatten(SkFlattenableWriteBuffer&);
36
37 static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
38
39 private:
40 SkScalar fRadius;
41 SkBlurMaskFilter::BlurStyle fBlurStyle;
42
43 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&);
44
45 typedef SkMaskFilter INHERITED;
46 };
47
Create(SkScalar radius,SkBlurMaskFilter::BlurStyle style)48 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style)
49 {
50 if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount)
51 return NULL;
52
53 return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style));
54 }
55
56 /////////////////////////////////////////////////////////////////////////////////////////////////////////
57
SkBlurMaskFilterImpl(SkScalar radius,SkBlurMaskFilter::BlurStyle style)58 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style)
59 : fRadius(radius), fBlurStyle(style)
60 {
61 #if 0
62 fGamma = NULL;
63 if (gammaScale)
64 {
65 fGamma = new U8[256];
66 if (gammaScale > 0)
67 SkBlurMask::BuildSqrGamma(fGamma, gammaScale);
68 else
69 SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale);
70 }
71 #endif
72 SkASSERT(radius >= 0);
73 SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount);
74 }
75
getFormat()76 SkMask::Format SkBlurMaskFilterImpl::getFormat()
77 {
78 return SkMask::kA8_Format;
79 }
80
filterMask(SkMask * dst,const SkMask & src,const SkMatrix & matrix,SkIPoint * margin)81 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin)
82 {
83 SkScalar radius = matrix.mapRadius(fRadius);
84 // To avoid unseemly allocation requests (esp. for finite platforms like
85 // handset) we limit the radius so something manageable. (as opposed to
86 // a request like 10,000)
87 static const SkScalar MAX_RADIUS = SkIntToScalar(128);
88 radius = SkMinScalar(radius, MAX_RADIUS);
89
90 if (SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle))
91 {
92 if (margin) {
93 // we need to integralize radius for our margin, so take the ceil
94 // just to be safe.
95 margin->set(SkScalarCeil(radius), SkScalarCeil(radius));
96 }
97 return true;
98 }
99 return false;
100 }
101
CreateProc(SkFlattenableReadBuffer & buffer)102 SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer)
103 {
104 return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer));
105 }
106
getFactory()107 SkFlattenable::Factory SkBlurMaskFilterImpl::getFactory()
108 {
109 return CreateProc;
110 }
111
SkBlurMaskFilterImpl(SkFlattenableReadBuffer & buffer)112 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer)
113 {
114 fRadius = buffer.readScalar();
115 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32();
116 SkASSERT(fRadius >= 0);
117 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
118 }
119
flatten(SkFlattenableWriteBuffer & buffer)120 void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer)
121 {
122 this->INHERITED::flatten(buffer);
123 buffer.writeScalar(fRadius);
124 buffer.write32(fBlurStyle);
125 }
126
127 ///////////////////////////////////////////////////////////////////////////////
128
129 static SkFlattenable::Registrar gReg("SkBlurMaskFilter",
130 SkBlurMaskFilterImpl::CreateProc);
131
132