1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #include "SkBlurMaskFilter.h"
11 : #include "SkBlurMask.h"
12 : #include "SkBuffer.h"
13 : #include "SkMaskFilter.h"
14 :
15 0 : class SkBlurMaskFilterImpl : public SkMaskFilter {
16 : public:
17 : SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle,
18 : uint32_t flags);
19 :
20 : // overrides from SkMaskFilter
21 : virtual SkMask::Format getFormat() SK_OVERRIDE;
22 : virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
23 : SkIPoint* margin) SK_OVERRIDE;
24 : virtual BlurType asABlur(BlurInfo*) const SK_OVERRIDE;
25 :
26 : // overrides from SkFlattenable
27 : virtual Factory getFactory() SK_OVERRIDE;
28 : virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
29 :
30 : static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
31 :
32 : private:
33 : SkScalar fRadius;
34 : SkBlurMaskFilter::BlurStyle fBlurStyle;
35 : uint32_t fBlurFlags;
36 :
37 : SkBlurMaskFilterImpl(SkFlattenableReadBuffer&);
38 :
39 : typedef SkMaskFilter INHERITED;
40 : };
41 :
42 0 : SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius,
43 : SkBlurMaskFilter::BlurStyle style,
44 : uint32_t flags) {
45 0 : if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount
46 : || flags > SkBlurMaskFilter::kAll_BlurFlag) {
47 0 : return NULL;
48 : }
49 :
50 0 : return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags));
51 : }
52 :
53 : ///////////////////////////////////////////////////////////////////////////////
54 :
55 0 : SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius,
56 : SkBlurMaskFilter::BlurStyle style,
57 : uint32_t flags)
58 0 : : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) {
59 : #if 0
60 : fGamma = NULL;
61 : if (gammaScale) {
62 : fGamma = new U8[256];
63 : if (gammaScale > 0)
64 : SkBlurMask::BuildSqrGamma(fGamma, gammaScale);
65 : else
66 : SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale);
67 : }
68 : #endif
69 0 : SkASSERT(radius >= 0);
70 0 : SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount);
71 0 : SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
72 0 : }
73 :
74 0 : SkMask::Format SkBlurMaskFilterImpl::getFormat() {
75 0 : return SkMask::kA8_Format;
76 : }
77 :
78 0 : bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
79 : const SkMatrix& matrix, SkIPoint* margin) {
80 : SkScalar radius;
81 0 : if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) {
82 0 : radius = fRadius;
83 : } else {
84 0 : radius = matrix.mapRadius(fRadius);
85 : }
86 :
87 : // To avoid unseemly allocation requests (esp. for finite platforms like
88 : // handset) we limit the radius so something manageable. (as opposed to
89 : // a request like 10,000)
90 0 : static const SkScalar MAX_RADIUS = SkIntToScalar(128);
91 0 : radius = SkMinScalar(radius, MAX_RADIUS);
92 : SkBlurMask::Quality blurQuality =
93 : (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
94 0 : SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality;
95 :
96 : return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle,
97 0 : blurQuality, margin);
98 : }
99 :
100 0 : SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer) {
101 0 : return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer));
102 : }
103 :
104 0 : SkFlattenable::Factory SkBlurMaskFilterImpl::getFactory() {
105 0 : return CreateProc;
106 : }
107 :
108 0 : SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer)
109 0 : : SkMaskFilter(buffer) {
110 0 : fRadius = buffer.readScalar();
111 0 : fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32();
112 0 : fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag;
113 0 : SkASSERT(fRadius >= 0);
114 0 : SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
115 0 : }
116 :
117 0 : void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) {
118 0 : this->INHERITED::flatten(buffer);
119 0 : buffer.writeScalar(fRadius);
120 0 : buffer.write32(fBlurStyle);
121 0 : buffer.write32(fBlurFlags);
122 0 : }
123 :
124 : static const SkMaskFilter::BlurType gBlurStyle2BlurType[] = {
125 : SkMaskFilter::kNormal_BlurType,
126 : SkMaskFilter::kSolid_BlurType,
127 : SkMaskFilter::kOuter_BlurType,
128 : SkMaskFilter::kInner_BlurType,
129 : };
130 :
131 0 : SkMaskFilter::BlurType SkBlurMaskFilterImpl::asABlur(BlurInfo* info) const {
132 0 : if (info) {
133 0 : info->fRadius = fRadius;
134 0 : info->fIgnoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
135 0 : info->fHighQuality = SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag);
136 : }
137 0 : return gBlurStyle2BlurType[fBlurStyle];
138 : }
139 :
140 : SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
141 2928 : SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
142 : SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
|