aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/SkBlurDrawLooper.cpp89
-rw-r--r--src/effects/SkBlurMask.cpp24
-rw-r--r--src/effects/SkBlurMask.h3
-rw-r--r--src/effects/SkBlurMaskFilter.cpp26
-rw-r--r--src/effects/SkEmbossMaskFilter.cpp6
-rw-r--r--src/effects/SkLayerDrawLooper.cpp44
6 files changed, 141 insertions, 51 deletions
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index 03e635be12..5af02db8ee 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -1,10 +1,10 @@
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#include "SkBlurDrawLooper.h"
#include "SkBlurMask.h" // just for SkBlurMask::ConvertRadiusToSigma
#include "SkBlurMaskFilter.h"
@@ -29,32 +29,27 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkColor color, SkScalar sigma,
this->init(sigma, dx, dy, color, flags);
}
-void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy,
- SkColor color, uint32_t flags) {
- fDx = dx;
- fDy = dy;
- fBlurColor = color;
- fBlurFlags = flags;
-
- SkASSERT(flags <= kAll_BlurFlag);
- if (sigma > 0) {
- uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
- SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
- SkBlurMaskFilter::kNone_BlurFlag;
-
- blurFlags |= flags & kHighQuality_BlurFlag ?
- SkBlurMaskFilter::kHighQuality_BlurFlag :
- SkBlurMaskFilter::kNone_BlurFlag;
-
- fBlur = SkBlurMaskFilter::Create(kNormal_SkBlurStyle, sigma, blurFlags);
+// only call from constructor
+void SkBlurDrawLooper::initEffects() {
+ SkASSERT(fBlurFlags <= kAll_BlurFlag);
+ if (fSigma > 0) {
+ uint32_t flags = fBlurFlags & kIgnoreTransform_BlurFlag ?
+ SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
+ SkBlurMaskFilter::kNone_BlurFlag;
+
+ flags |= fBlurFlags & kHighQuality_BlurFlag ?
+ SkBlurMaskFilter::kHighQuality_BlurFlag :
+ SkBlurMaskFilter::kNone_BlurFlag;
+
+ fBlur = SkBlurMaskFilter::Create(kNormal_SkBlurStyle, fSigma, flags);
} else {
fBlur = NULL;
}
-
- if (flags & kOverrideColor_BlurFlag) {
+
+ if (fBlurFlags & kOverrideColor_BlurFlag) {
// Set alpha to 1 for the override since transparency will already
// be baked into the blurred mask.
- SkColor opaqueColor = SkColorSetA(color, 255);
+ SkColor opaqueColor = SkColorSetA(fBlurColor, 255);
//The SrcIn xfer mode will multiply 'color' by the incoming alpha
fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
SkXfermode::kSrcIn_Mode);
@@ -63,32 +58,60 @@ void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy,
}
}
-SkBlurDrawLooper::SkBlurDrawLooper(SkReadBuffer& buffer)
-: INHERITED(buffer) {
+void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy,
+ SkColor color, uint32_t flags) {
+ fSigma = sigma;
+ fDx = dx;
+ fDy = dy;
+ fBlurColor = color;
+ fBlurFlags = flags;
+
+ this->initEffects();
+}
+
+SkBlurDrawLooper::SkBlurDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {
+ fSigma = buffer.readScalar();
fDx = buffer.readScalar();
fDy = buffer.readScalar();
fBlurColor = buffer.readColor();
- fBlur = buffer.readMaskFilter();
- fColorFilter = buffer.readColorFilter();
fBlurFlags = buffer.readUInt() & kAll_BlurFlag;
-}
-SkBlurDrawLooper::~SkBlurDrawLooper() {
- SkSafeUnref(fBlur);
- SkSafeUnref(fColorFilter);
+ this->initEffects();
}
void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
+ buffer.writeScalar(fSigma);
buffer.writeScalar(fDx);
buffer.writeScalar(fDy);
buffer.writeColor(fBlurColor);
- buffer.writeFlattenable(fBlur);
- buffer.writeFlattenable(fColorFilter);
- buffer.writeUInt(fBlurFlags);
+ buffer.write32(fBlurFlags);
+}
+
+SkBlurDrawLooper::~SkBlurDrawLooper() {
+ SkSafeUnref(fBlur);
+ SkSafeUnref(fColorFilter);
}
+bool SkBlurDrawLooper::asABlurShadow(BlurShadowRec* rec) const {
+ if (fSigma <= 0 || (fBlurFlags & fBlurFlags & kIgnoreTransform_BlurFlag)) {
+ return false;
+ }
+
+ if (rec) {
+ rec->fSigma = fSigma;
+ rec->fColor = fBlurColor;
+ rec->fOffset.set(fDx, fDy);
+ rec->fStyle = kNormal_SkBlurStyle;
+ rec->fQuality = (fBlurFlags & kHighQuality_BlurFlag) ?
+ kHigh_SkBlurQuality : kLow_SkBlurQuality;
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
SkDrawLooper::Context* SkBlurDrawLooper::createContext(SkCanvas*, void* storage) const {
return SkNEW_PLACEMENT_ARGS(storage, BlurDrawLooperContext, (this));
}
diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
index c04a6f89f8..bf50845ab6 100644
--- a/src/effects/SkBlurMask.cpp
+++ b/src/effects/SkBlurMask.cpp
@@ -13,17 +13,21 @@
#include "SkEndian.h"
+// This constant approximates the scaling done in the software path's
+// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
+// IMHO, it actually should be 1: we blur "less" than we should do
+// according to the CSS and canvas specs, simply because Safari does the same.
+// Firefox used to do the same too, until 4.0 where they fixed it. So at some
+// point we should probably get rid of these scaling constants and rebaseline
+// all the blur tests.
+static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f;
+
SkScalar SkBlurMask::ConvertRadiusToSigma(SkScalar radius) {
- // This constant approximates the scaling done in the software path's
- // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
- // IMHO, it actually should be 1: we blur "less" than we should do
- // according to the CSS and canvas specs, simply because Safari does the same.
- // Firefox used to do the same too, until 4.0 where they fixed it. So at some
- // point we should probably get rid of these scaling constants and rebaseline
- // all the blur tests.
- static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f;
-
- return radius ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
+ return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
+}
+
+SkScalar SkBlurMask::ConvertSigmaToRadius(SkScalar sigma) {
+ return sigma > 0.5f ? (sigma - 0.5f) / kBLUR_SIGMA_SCALE : 0.0f;
}
#define UNROLL_SEPARABLE_LOOPS
diff --git a/src/effects/SkBlurMask.h b/src/effects/SkBlurMask.h
index 39adb96f9a..71f60d91fa 100644
--- a/src/effects/SkBlurMask.h
+++ b/src/effects/SkBlurMask.h
@@ -39,7 +39,10 @@ public:
static bool BlurGroundTruth(SkScalar sigma, SkMask* dst, const SkMask& src, SkBlurStyle,
SkIPoint* margin = NULL);
+ // If radius > 0, return the corresponding sigma, else return 0
static SkScalar ConvertRadiusToSigma(SkScalar radius);
+ // If sigma > 0.5, return the corresponding radius, else return 0
+ static SkScalar ConvertSigmaToRadius(SkScalar sigma);
/* Helper functions for analytic rectangle blurs */
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 2bed2fe8d6..5dffd6fd1f 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -59,6 +59,7 @@ public:
#endif
virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
+ virtual bool asABlur(BlurRec*) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl)
@@ -87,6 +88,11 @@ private:
SkBlurStyle fBlurStyle;
uint32_t fBlurFlags;
+ SkBlurQuality getQuality() const {
+ return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
+ kHigh_SkBlurQuality : kLow_SkBlurQuality;
+ }
+
SkBlurMaskFilterImpl(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
@@ -145,16 +151,24 @@ SkMask::Format SkBlurMaskFilterImpl::getFormat() const {
return SkMask::kA8_Format;
}
+bool SkBlurMaskFilterImpl::asABlur(BlurRec* rec) const {
+ if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) {
+ return false;
+ }
+
+ if (rec) {
+ rec->fSigma = fSigma;
+ rec->fStyle = fBlurStyle;
+ rec->fQuality = this->getQuality();
+ }
+ return true;
+}
+
bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
const SkMatrix& matrix,
SkIPoint* margin) const{
SkScalar sigma = this->computeXformedSigma(matrix);
-
- SkBlurQuality blurQuality =
- (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
- kHigh_SkBlurQuality : kLow_SkBlurQuality;
-
- return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, blurQuality, margin);
+ return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, this->getQuality(), margin);
}
bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r,
diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp
index 9bf5025e70..cdd55fcc5b 100644
--- a/src/effects/SkEmbossMaskFilter.cpp
+++ b/src/effects/SkEmbossMaskFilter.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2006 The Android Open Source Project
*
@@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
-
#include "SkEmbossMaskFilter.h"
#include "SkBlurMaskFilter.h"
#include "SkBlurMask.h"
@@ -15,6 +13,10 @@
#include "SkWriteBuffer.h"
#include "SkString.h"
+SkEmbossMaskFilter* SkEmbossMaskFilter::Create(SkScalar blurSigma, const Light& light) {
+ return SkNEW_ARGS(SkEmbossMaskFilter, (blurSigma, light));
+}
+
static inline int pin2byte(int n) {
if (n < 0) {
n = 0;
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index fa590d2d3f..aed2c9bbd4 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -153,6 +153,50 @@ bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
return true;
}
+bool SkLayerDrawLooper::asABlurShadow(BlurShadowRec* bsRec) const {
+ if (fCount != 2) {
+ return false;
+ }
+ const Rec* rec = fRecs;
+
+ // bottom layer needs to be just blur(maskfilter)
+ if ((rec->fInfo.fPaintBits & ~kMaskFilter_Bit)) {
+ return false;
+ }
+ if (SkXfermode::kSrc_Mode != rec->fInfo.fColorMode) {
+ return false;
+ }
+ const SkMaskFilter* mf = rec->fPaint.getMaskFilter();
+ if (NULL == mf) {
+ return false;
+ }
+ SkMaskFilter::BlurRec maskBlur;
+ if (!mf->asABlur(&maskBlur)) {
+ return false;
+ }
+
+ rec = rec->fNext;
+ // top layer needs to be "plain"
+ if (rec->fInfo.fPaintBits) {
+ return false;
+ }
+ if (SkXfermode::kDst_Mode != rec->fInfo.fColorMode) {
+ return false;
+ }
+ if (!rec->fInfo.fOffset.equals(0, 0)) {
+ return false;
+ }
+
+ if (bsRec) {
+ bsRec->fSigma = maskBlur.fSigma;
+ bsRec->fOffset = fRecs->fInfo.fOffset;
+ bsRec->fColor = fRecs->fPaint.getColor();
+ bsRec->fStyle = maskBlur.fStyle;
+ bsRec->fQuality = maskBlur.fQuality;
+ }
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {