SkBlurMaskFilter.cpp revision 40528743dbb9ce7f39f093e0cdc47849ac8887cf
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);
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle))
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
102af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project        if (margin) {
103af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project            // we need to integralize radius for our margin, so take the ceil
104af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project            // just to be safe.
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            margin->set(SkScalarCeil(radius), SkScalarCeil(radius));
106af527e02dce280c269d751322e9f60aac8cb97daThe Android Open Source Project        }
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkFlattenableReadBuffer& buffer)
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(SkBlurMaskFilterImpl, (buffer));
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkBlurMaskFilterImpl::getFactory()
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return CreateProc;
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer)
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRadius = buffer.readScalar();
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32();
12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fRadius >= 0);
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer)
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(fRadius);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fBlurStyle);
13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    buffer.write32(fBlurFlags);
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkFlattenable::Registrar gReg("SkBlurMaskFilter",
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                     SkBlurMaskFilterImpl::CreateProc);
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
144