gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,171 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2011 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +#include "SkBlurDrawLooper.h"
    1.12 +#include "SkBlurMask.h"     // just for SkBlurMask::ConvertRadiusToSigma
    1.13 +#include "SkBlurMaskFilter.h"
    1.14 +#include "SkCanvas.h"
    1.15 +#include "SkColorFilter.h"
    1.16 +#include "SkReadBuffer.h"
    1.17 +#include "SkWriteBuffer.h"
    1.18 +#include "SkMaskFilter.h"
    1.19 +#include "SkPaint.h"
    1.20 +#include "SkString.h"
    1.21 +#include "SkStringUtils.h"
    1.22 +
    1.23 +SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
    1.24 +                                   SkColor color, uint32_t flags) {
    1.25 +    this->init(SkBlurMask::ConvertRadiusToSigma(radius), dx, dy, color, flags);
    1.26 +}
    1.27 +
    1.28 +SkBlurDrawLooper::SkBlurDrawLooper(SkColor color, SkScalar sigma,
    1.29 +                                   SkScalar dx, SkScalar dy, uint32_t flags) {
    1.30 +    this->init(sigma, dx, dy, color, flags);
    1.31 +}
    1.32 +
    1.33 +void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy,
    1.34 +                            SkColor color, uint32_t flags) {
    1.35 +    fDx = dx;
    1.36 +    fDy = dy;
    1.37 +    fBlurColor = color;
    1.38 +    fBlurFlags = flags;
    1.39 +
    1.40 +    SkASSERT(flags <= kAll_BlurFlag);
    1.41 +    if (sigma > 0) {
    1.42 +        uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
    1.43 +            SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
    1.44 +            SkBlurMaskFilter::kNone_BlurFlag;
    1.45 +
    1.46 +        blurFlags |= flags & kHighQuality_BlurFlag ?
    1.47 +            SkBlurMaskFilter::kHighQuality_BlurFlag :
    1.48 +            SkBlurMaskFilter::kNone_BlurFlag;
    1.49 +
    1.50 +        fBlur = SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle,
    1.51 +                                         sigma,
    1.52 +                                         blurFlags);
    1.53 +    } else {
    1.54 +        fBlur = NULL;
    1.55 +    }
    1.56 +
    1.57 +    if (flags & kOverrideColor_BlurFlag) {
    1.58 +        // Set alpha to 1 for the override since transparency will already
    1.59 +        // be baked into the blurred mask.
    1.60 +        SkColor opaqueColor = SkColorSetA(color, 255);
    1.61 +        //The SrcIn xfer mode will multiply 'color' by the incoming alpha
    1.62 +        fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
    1.63 +                                                       SkXfermode::kSrcIn_Mode);
    1.64 +    } else {
    1.65 +        fColorFilter = NULL;
    1.66 +    }
    1.67 +}
    1.68 +
    1.69 +SkBlurDrawLooper::SkBlurDrawLooper(SkReadBuffer& buffer)
    1.70 +: INHERITED(buffer) {
    1.71 +
    1.72 +    fDx = buffer.readScalar();
    1.73 +    fDy = buffer.readScalar();
    1.74 +    fBlurColor = buffer.readColor();
    1.75 +    fBlur = buffer.readMaskFilter();
    1.76 +    fColorFilter = buffer.readColorFilter();
    1.77 +    fBlurFlags = buffer.readUInt() & kAll_BlurFlag;
    1.78 +}
    1.79 +
    1.80 +SkBlurDrawLooper::~SkBlurDrawLooper() {
    1.81 +    SkSafeUnref(fBlur);
    1.82 +    SkSafeUnref(fColorFilter);
    1.83 +}
    1.84 +
    1.85 +void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const {
    1.86 +    this->INHERITED::flatten(buffer);
    1.87 +    buffer.writeScalar(fDx);
    1.88 +    buffer.writeScalar(fDy);
    1.89 +    buffer.writeColor(fBlurColor);
    1.90 +    buffer.writeFlattenable(fBlur);
    1.91 +    buffer.writeFlattenable(fColorFilter);
    1.92 +    buffer.writeUInt(fBlurFlags);
    1.93 +}
    1.94 +
    1.95 +SkDrawLooper::Context* SkBlurDrawLooper::createContext(SkCanvas*, void* storage) const {
    1.96 +    return SkNEW_PLACEMENT_ARGS(storage, BlurDrawLooperContext, (this));
    1.97 +}
    1.98 +
    1.99 +SkBlurDrawLooper::BlurDrawLooperContext::BlurDrawLooperContext(
   1.100 +        const SkBlurDrawLooper* looper)
   1.101 +    : fLooper(looper), fState(SkBlurDrawLooper::kBeforeEdge) {}
   1.102 +
   1.103 +bool SkBlurDrawLooper::BlurDrawLooperContext::next(SkCanvas* canvas,
   1.104 +                                                   SkPaint* paint) {
   1.105 +    switch (fState) {
   1.106 +        case kBeforeEdge:
   1.107 +            // we do nothing if a maskfilter is already installed
   1.108 +            if (paint->getMaskFilter()) {
   1.109 +                fState = kDone;
   1.110 +                return false;
   1.111 +            }
   1.112 +#ifdef SK_BUILD_FOR_ANDROID
   1.113 +            SkColor blurColor;
   1.114 +            blurColor = fLooper->fBlurColor;
   1.115 +            if (SkColorGetA(blurColor) == 255) {
   1.116 +                blurColor = SkColorSetA(blurColor, paint->getAlpha());
   1.117 +            }
   1.118 +            paint->setColor(blurColor);
   1.119 +#else
   1.120 +            paint->setColor(fLooper->fBlurColor);
   1.121 +#endif
   1.122 +            paint->setMaskFilter(fLooper->fBlur);
   1.123 +            paint->setColorFilter(fLooper->fColorFilter);
   1.124 +            canvas->save(SkCanvas::kMatrix_SaveFlag);
   1.125 +            if (fLooper->fBlurFlags & kIgnoreTransform_BlurFlag) {
   1.126 +                SkMatrix transform(canvas->getTotalMatrix());
   1.127 +                transform.postTranslate(fLooper->fDx, fLooper->fDy);
   1.128 +                canvas->setMatrix(transform);
   1.129 +            } else {
   1.130 +                canvas->translate(fLooper->fDx, fLooper->fDy);
   1.131 +            }
   1.132 +            fState = kAfterEdge;
   1.133 +            return true;
   1.134 +        case kAfterEdge:
   1.135 +            canvas->restore();
   1.136 +            fState = kDone;
   1.137 +            return true;
   1.138 +        default:
   1.139 +            SkASSERT(kDone == fState);
   1.140 +            return false;
   1.141 +    }
   1.142 +}
   1.143 +
   1.144 +#ifndef SK_IGNORE_TO_STRING
   1.145 +void SkBlurDrawLooper::toString(SkString* str) const {
   1.146 +    str->append("SkBlurDrawLooper: ");
   1.147 +
   1.148 +    str->append("dx: ");
   1.149 +    str->appendScalar(fDx);
   1.150 +
   1.151 +    str->append(" dy: ");
   1.152 +    str->appendScalar(fDy);
   1.153 +
   1.154 +    str->append(" color: ");
   1.155 +    str->appendHex(fBlurColor);
   1.156 +
   1.157 +    str->append(" flags: (");
   1.158 +    if (kNone_BlurFlag == fBlurFlags) {
   1.159 +        str->append("None");
   1.160 +    } else {
   1.161 +        bool needsSeparator = false;
   1.162 +        SkAddFlagToString(str, SkToBool(kIgnoreTransform_BlurFlag & fBlurFlags), "IgnoreTransform",
   1.163 +                          &needsSeparator);
   1.164 +        SkAddFlagToString(str, SkToBool(kOverrideColor_BlurFlag & fBlurFlags), "OverrideColor",
   1.165 +                          &needsSeparator);
   1.166 +        SkAddFlagToString(str, SkToBool(kHighQuality_BlurFlag & fBlurFlags), "HighQuality",
   1.167 +                          &needsSeparator);
   1.168 +    }
   1.169 +    str->append(")");
   1.170 +
   1.171 +    // TODO: add optional "fBlurFilter->toString(str);" when SkMaskFilter::toString is added
   1.172 +    // alternatively we could cache the radius in SkBlurDrawLooper and just add it here
   1.173 +}
   1.174 +#endif

mercurial