Home | History | Annotate | Download | only in effects
      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