diff options
-rw-r--r-- | bench/BlurRectBench.cpp | 4 | ||||
-rw-r--r-- | gm/blurrect.cpp | 21 | ||||
-rw-r--r-- | gm/blurs.cpp | 22 | ||||
-rw-r--r-- | gm/circles.cpp | 2 | ||||
-rw-r--r-- | gm/rects.cpp | 2 | ||||
-rw-r--r-- | gm/shadows.cpp | 10 | ||||
-rw-r--r-- | include/core/SkPicture.h | 1 | ||||
-rw-r--r-- | include/effects/SkBlurDrawLooper.h | 6 | ||||
-rw-r--r-- | include/effects/SkBlurMaskFilter.h | 24 | ||||
-rw-r--r-- | include/effects/SkEmbossMaskFilter.h | 5 | ||||
-rw-r--r-- | samplecode/SampleAll.cpp | 11 | ||||
-rw-r--r-- | samplecode/SampleXfermodesBlur.cpp | 3 | ||||
-rw-r--r-- | src/animator/SkDrawEmboss.cpp | 17 | ||||
-rw-r--r-- | src/animator/SkDrawEmboss.h | 10 | ||||
-rw-r--r-- | src/core/SkPicture.cpp | 1 | ||||
-rw-r--r-- | src/effects/SkBlurDrawLooper.cpp | 25 | ||||
-rw-r--r-- | src/effects/SkBlurMask.cpp | 98 | ||||
-rw-r--r-- | src/effects/SkBlurMask.h | 36 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 135 | ||||
-rw-r--r-- | src/effects/SkEmbossMaskFilter.cpp | 46 |
20 files changed, 281 insertions, 198 deletions
diff --git a/bench/BlurRectBench.cpp b/bench/BlurRectBench.cpp index 3d0a896283..1f40780fc2 100644 --- a/bench/BlurRectBench.cpp +++ b/bench/BlurRectBench.cpp @@ -141,8 +141,8 @@ protected: SkMask mask; mask.fImage = NULL; SkBlurMask::Blur(&mask, fSrcMask, this->radius(), - SkBlurMask::kNormal_Style, - SkBlurMask::kHigh_Quality); + SkBlurMask::kNormal_Style, + SkBlurMask::kHigh_Quality); SkMask::FreeImage(mask.fImage); } private: diff --git a/gm/blurrect.cpp b/gm/blurrect.cpp index 5a18d16fad..2cb962f24c 100644 --- a/gm/blurrect.cpp +++ b/gm/blurrect.cpp @@ -71,12 +71,12 @@ class BlurRectGM : public skiagm::GM { SkAlpha fAlpha; public: BlurRectGM(const char name[], PaintProc pproc, U8CPU alpha, - SkBlurMaskFilter::BlurStyle bs) : - fMaskFilter(SkBlurMaskFilter::Create(STROKE_WIDTH/2, bs, - SkBlurMaskFilter::kHighQuality_BlurFlag)) - , fName(name) - , fPProc(pproc) - , fAlpha(SkToU8(alpha)) { + SkBlurMaskFilter::BlurStyle bs) + : fMaskFilter(SkBlurMaskFilter::Create(STROKE_WIDTH/2, bs, + SkBlurMaskFilter::kHighQuality_BlurFlag)) + , fName(name) + , fPProc(pproc) + , fAlpha(SkToU8(alpha)) { fName.appendf("_%s", gBlurStyle2Name[bs]); } @@ -208,13 +208,12 @@ private: class BlurRectFastGM: public BlurRectCompareGM { public: - BlurRectFastGM(const char name[], unsigned int rect_width, - unsigned int rect_height, float blur_radius, + BlurRectFastGM(const char name[], unsigned int rectWidth, + unsigned int rectHeight, float blurRadius, SkBlurMask::Style style) : - INHERITED(name, rect_width, rect_height, blur_radius, style) - { - + INHERITED(name, rectWidth, rectHeight, blurRadius, style) { } + protected: virtual bool makeMask(SkMask *m, const SkRect& r) SK_OVERRIDE { return SkBlurMask::BlurRect(m, r, this->radius(), this->style()); diff --git a/gm/blurs.cpp b/gm/blurs.cpp index 22804c7fa1..988fbe2943 100644 --- a/gm/blurs.cpp +++ b/gm/blurs.cpp @@ -60,31 +60,29 @@ protected: for (size_t i = 0; i < SK_ARRAY_COUNT(gRecs); i++) { if (gRecs[i].fStyle != NONE) { SkMaskFilter* mf = SkBlurMaskFilter::Create( - SkIntToScalar(20), gRecs[i].fStyle, flags - ); + SkIntToScalar(20), gRecs[i].fStyle, flags); paint.setMaskFilter(mf)->unref(); } else { paint.setMaskFilter(NULL); } - canvas->drawCircle(SkIntToScalar(200 + gRecs[i].fCx*100) - , SkIntToScalar(200 + gRecs[i].fCy*100) - , SkIntToScalar(50) - , paint); + canvas->drawCircle(SkIntToScalar(200 + gRecs[i].fCx*100), + SkIntToScalar(200 + gRecs[i].fCy*100), + SkIntToScalar(50), + paint); } // draw text { SkMaskFilter* mf = SkBlurMaskFilter::Create( - SkIntToScalar(4) - , SkBlurMaskFilter::kNormal_BlurStyle - , flags - ); + SkIntToScalar(4), + SkBlurMaskFilter::kNormal_BlurStyle, + flags); paint.setMaskFilter(mf)->unref(); SkScalar x = SkIntToScalar(70); SkScalar y = SkIntToScalar(400); paint.setColor(SK_ColorBLACK); canvas->drawText("Hamburgefons Style", 18, x, y, paint); - canvas->drawText("Hamburgefons Style", 18 - , x, y + SkIntToScalar(50), paint); + canvas->drawText("Hamburgefons Style", 18, + x, y + SkIntToScalar(50), paint); paint.setMaskFilter(NULL); paint.setColor(SK_ColorWHITE); x -= SkIntToScalar(2); diff --git a/gm/circles.cpp b/gm/circles.cpp index 4513934ab6..1fe114a287 100644 --- a/gm/circles.cpp +++ b/gm/circles.cpp @@ -83,7 +83,7 @@ protected: SkIntToScalar(10), 0xFF0000FF, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL0(shadowLooper); p.setLooper(shadowLooper); fPaints.push_back(p); diff --git a/gm/rects.cpp b/gm/rects.cpp index eee92b35af..f2fa989a4d 100644 --- a/gm/rects.cpp +++ b/gm/rects.cpp @@ -88,7 +88,7 @@ protected: SkIntToScalar(10), SK_ColorWHITE, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL0(shadowLooper); p.setLooper(shadowLooper); fPaints.push_back(p); diff --git a/gm/shadows.cpp b/gm/shadows.cpp index 2fb1615cf9..d7a12548cd 100644 --- a/gm/shadows.cpp +++ b/gm/shadows.cpp @@ -50,33 +50,33 @@ protected: SkIntToScalar(10), 0xFF0000FF, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL0(shadowLoopers[0]); shadowLoopers[1] = new SkBlurDrawLooper (SkIntToScalar(10), SkIntToScalar(5), SkIntToScalar(10), 0xFF0000FF, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | - SkBlurDrawLooper::kOverrideColor_BlurFlag ); + SkBlurDrawLooper::kOverrideColor_BlurFlag); SkAutoUnref aurL1(shadowLoopers[1]); shadowLoopers[2] = new SkBlurDrawLooper (SkIntToScalar(5), SkIntToScalar(5), SkIntToScalar(10), 0xFF000000, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL2(shadowLoopers[2]); shadowLoopers[3] = new SkBlurDrawLooper (SkIntToScalar(5), SkIntToScalar(-5), SkIntToScalar(-10), 0x7FFF0000, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL3(shadowLoopers[3]); shadowLoopers[4] = new SkBlurDrawLooper (SkIntToScalar(0), SkIntToScalar(5), SkIntToScalar(5), 0xFF000000, SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | - SkBlurDrawLooper::kHighQuality_BlurFlag ); + SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL4(shadowLoopers[4]); static const struct { diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 95034c2a72..39fd7c02b6 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -209,6 +209,7 @@ protected: // V11: modify how readBitmap and writeBitmap store their info. // V12: add conics to SkPath, use new SkPathRef flattening // V13: add flag to drawBitmapRectToRect + // parameterize blurs by sigma rather than radius #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO static const uint32_t PRIOR_PICTURE_VERSION = 12; // TODO: remove when .skps regenerated #endif diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h index e968857889..8e0c2dd001 100644 --- a/include/effects/SkBlurDrawLooper.h +++ b/include/effects/SkBlurDrawLooper.h @@ -35,6 +35,10 @@ public: kAll_BlurFlag = 0x07 }; + SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy, + uint32_t flags = kNone_BlurFlag); + + // DEPRECATED - radius-based SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags = kNone_BlurFlag); virtual ~SkBlurDrawLooper(); @@ -64,6 +68,8 @@ private: }; State fState; + void init(SkScalar sigma, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags); + typedef SkDrawLooper INHERITED; }; diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h index 2ab321aa7a..81c0ceb80d 100644 --- a/include/effects/SkBlurMaskFilter.h +++ b/include/effects/SkBlurMaskFilter.h @@ -33,27 +33,39 @@ public: kAll_BlurFlag = 0x03 }; + /** + * DEPRECATED - radius-based + */ + static SkMaskFilter* Create(SkScalar radius, BlurStyle style, + uint32_t flags = kNone_BlurFlag); + /** Create a blur maskfilter. - @param radius The radius to extend the blur from the original mask. Must be > 0. @param style The BlurStyle to use + @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0. @param flags Flags to use - defaults to none @return The new blur maskfilter */ - static SkMaskFilter* Create(SkScalar radius, BlurStyle style, + static SkMaskFilter* Create(BlurStyle style, SkScalar sigma, uint32_t flags = kNone_BlurFlag); /** Create an emboss maskfilter + @param blurSigma standard deviation of the Gaussian blur to apply + before applying lighting (e.g. 3) @param direction array of 3 scalars [x, y, z] specifying the direction of the light source @param ambient 0...1 amount of ambient light @param specular coefficient for specular highlights (e.g. 8) - @param blurRadius amount to blur before applying lighting (e.g. 3) @return the emboss maskfilter */ - static SkMaskFilter* CreateEmboss( const SkScalar direction[3], - SkScalar ambient, SkScalar specular, - SkScalar blurRadius); + static SkMaskFilter* CreateEmboss(SkScalar blurSigma, const SkScalar direction[3], + SkScalar ambient, SkScalar specular); + + // DEPRECATED - radius-based + static SkMaskFilter* CreateEmboss(const SkScalar direction[3], + SkScalar ambient, SkScalar specular, + SkScalar blurRadius); SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() + private: SkBlurMaskFilter(); // can't be instantiated }; diff --git a/include/effects/SkEmbossMaskFilter.h b/include/effects/SkEmbossMaskFilter.h index c6679200b3..4b5bd6f983 100644 --- a/include/effects/SkEmbossMaskFilter.h +++ b/include/effects/SkEmbossMaskFilter.h @@ -23,6 +23,9 @@ public: uint8_t fSpecular; // exponent, 4.4 right now }; + SkEmbossMaskFilter(SkScalar blurSigma, const Light& light); + + // DEPRECATED - radius-based SkEmbossMaskFilter(const Light& light, SkScalar blurRadius); // overrides from SkMaskFilter @@ -41,7 +44,7 @@ protected: private: Light fLight; - SkScalar fBlurRadius; + SkScalar fBlurSigma; typedef SkMaskFilter INHERITED; }; diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp index 01fbe0f8ec..de99be70cb 100644 --- a/samplecode/SampleAll.cpp +++ b/samplecode/SampleAll.cpp @@ -80,7 +80,8 @@ private: static void r0(SkLayerRasterizer* rast, SkPaint& p) { p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3), - SkBlurMaskFilter::kNormal_BlurStyle))->unref(); + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kNone_BlurFlag))->unref(); rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3)); p.setMaskFilter(NULL); @@ -254,7 +255,10 @@ static void apply_shader(SkPaint* paint, int index) { #if 1 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 }; - paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref(); + paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, + SK_Scalar1/4, + SkIntToScalar(4), + SkIntToScalar(3)))->unref(); paint->setColor(SK_ColorBLUE); #endif } @@ -383,8 +387,7 @@ protected: light.fAmbient = 0x48; light.fSpecular = 0x80; SkScalar radius = SkIntToScalar(12)/5; - SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light, - radius); + SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light, radius); SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode); SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter( diff --git a/samplecode/SampleXfermodesBlur.cpp b/samplecode/SampleXfermodesBlur.cpp index ec5909b06c..a4ca9e7952 100644 --- a/samplecode/SampleXfermodesBlur.cpp +++ b/samplecode/SampleXfermodesBlur.cpp @@ -46,7 +46,8 @@ class XfermodesBlurView : public SampleView { void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha, SkScalar x, SkScalar y) { SkPaint p; - SkMaskFilter* mf = SkBlurMaskFilter::Create(5, SkBlurMaskFilter::kNormal_BlurStyle, 0); + SkMaskFilter* mf = SkBlurMaskFilter::Create(5, SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kNone_BlurFlag); p.setMaskFilter(mf)->unref(); SkScalar ww = SkIntToScalar(W); diff --git a/src/animator/SkDrawEmboss.cpp b/src/animator/SkDrawEmboss.cpp index 5eed370a5d..a0084eb2fd 100644 --- a/src/animator/SkDrawEmboss.cpp +++ b/src/animator/SkDrawEmboss.cpp @@ -12,22 +12,23 @@ #if SK_USE_CONDENSED_INFO == 0 const SkMemberInfo SkDrawEmboss::fInfo[] = { - SK_MEMBER(ambient, Float), - SK_MEMBER_ARRAY(direction, Float), - SK_MEMBER(radius, Float), - SK_MEMBER(specular, Float) + SK_MEMBER(fAmbient, Float), + SK_MEMBER_ARRAY(fDirection, Float), + SK_MEMBER(fSigma, Float), + SK_MEMBER(fSpecular, Float) }; #endif DEFINE_GET_MEMBER(SkDrawEmboss); -SkDrawEmboss::SkDrawEmboss() : radius(-1) { - direction.setCount(3); +SkDrawEmboss::SkDrawEmboss() : fSigma(-1) { + fDirection.setCount(3); } SkMaskFilter* SkDrawEmboss::getMaskFilter() { - if (radius < 0 || direction.count() !=3) + if (fSigma < 0 || fDirection.count() !=3) return NULL; - return SkBlurMaskFilter::CreateEmboss(direction.begin(), ambient, specular, radius); + return SkBlurMaskFilter::CreateEmboss(fSigma, fDirection.begin(), + fAmbient, fSpecular); } diff --git a/src/animator/SkDrawEmboss.h b/src/animator/SkDrawEmboss.h index 6e6199753c..7ffd3ef841 100644 --- a/src/animator/SkDrawEmboss.h +++ b/src/animator/SkDrawEmboss.h @@ -15,10 +15,14 @@ class SkDrawEmboss : public SkDrawMaskFilter { DECLARE_DRAW_MEMBER_INFO(Emboss); SkDrawEmboss(); - virtual SkMaskFilter* getMaskFilter(); + virtual SkMaskFilter* getMaskFilter() SK_OVERRIDE; protected: - SkTDScalarArray direction; - SkScalar radius, ambient, specular; + SkTDScalarArray fDirection; + SkScalar fSigma; + SkScalar fAmbient; + SkScalar fSpecular; + + typedef SkDrawMaskFilter INHERITED; }; #endif // SkDrawEmboss_DEFINED diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 097e0ea0c7..c94641b09b 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -275,6 +275,7 @@ bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { } if (PICTURE_VERSION != info.fVersion #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO + // V13 is backwards compatible with V12 && PRIOR_PICTURE_VERSION != info.fVersion // TODO: remove when .skps regenerated #endif ) { diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp index 9585214b29..fb0153c2e7 100644 --- a/src/effects/SkBlurDrawLooper.cpp +++ b/src/effects/SkBlurDrawLooper.cpp @@ -6,6 +6,7 @@ * found in the LICENSE file. */ #include "SkBlurDrawLooper.h" +#include "SkBlurMask.h" // just for SkBlurMask::ConvertRadiusToSigma #include "SkBlurMaskFilter.h" #include "SkCanvas.h" #include "SkColorFilter.h" @@ -16,11 +17,25 @@ #include "SkStringUtils.h" SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, - SkColor color, uint32_t flags) - : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags), fState(kDone) { + SkColor color, uint32_t flags) { + this->init(SkBlurMask::ConvertRadiusToSigma(radius), dx, dy, color, flags); +} + +SkBlurDrawLooper::SkBlurDrawLooper(SkColor color, SkScalar sigma, + SkScalar dx, SkScalar dy, uint32_t flags) { + 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; + fState = kDone; SkASSERT(flags <= kAll_BlurFlag); - if (radius > 0) { + if (sigma > 0) { uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ? SkBlurMaskFilter::kIgnoreTransform_BlurFlag : SkBlurMaskFilter::kNone_BlurFlag; @@ -29,8 +44,8 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkBlurMaskFilter::kHighQuality_BlurFlag : SkBlurMaskFilter::kNone_BlurFlag; - fBlur = SkBlurMaskFilter::Create(radius, - SkBlurMaskFilter::kNormal_BlurStyle, + fBlur = SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle, + sigma, blurFlags); } else { fBlur = NULL; diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp index c946c5eb4b..a8ae1d3133 100644 --- a/src/effects/SkBlurMask.cpp +++ b/src/effects/SkBlurMask.cpp @@ -12,7 +12,19 @@ #include "SkTemplates.h" #include "SkEndian.h" -const SkScalar SkBlurMask::kBlurRadiusFudgeFactor = SkFloatToScalar(.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 = SkFloatToScalar(0.57735f); + + return radius ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f; +} #define UNROLL_SEPARABLE_LOOPS @@ -473,24 +485,40 @@ void SkMask_FreeImage(uint8_t* image) { bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, SkScalar radius, Style style, Quality quality, - SkIPoint* margin) -{ + SkIPoint* margin) { + return SkBlurMask::BoxBlur(dst, src, + SkBlurMask::ConvertRadiusToSigma(radius), + style, quality, margin); +} + +bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, + SkScalar sigma, Style style, Quality quality, + SkIPoint* margin) { if (src.fFormat != SkMask::kA8_Format) { return false; } // Force high quality off for small radii (performance) - if (radius < SkIntToScalar(3)) { + if (sigma <= SkIntToScalar(2)) { quality = kLow_Quality; } + SkScalar passRadius; + if (kHigh_Quality == quality) { + // For the high quality path the 3 pass box blur kernel width is + // 6*rad+1 while the full Gaussian width is 6*sigma. + passRadius = sigma - (1/6.0f); + } else { + // For the low quality path we only attempt to cover 3*sigma of the + // Gaussian blur area (1.5*sigma on each side). The single pass box + // blur's kernel size is 2*rad+1. + passRadius = 1.5f*sigma - 0.5f; + } + // highQuality: use three box blur passes as a cheap way // to approximate a Gaussian blur int passCount = (kHigh_Quality == quality) ? 3 : 1; - SkScalar passRadius = (kHigh_Quality == quality) ? - SkScalarMul( radius, kBlurRadiusFudgeFactor): - radius; int rx = SkScalarCeil(passRadius); int outerWeight = 255 - SkScalarRound((SkIntToScalar(rx) - passRadius) * 255); @@ -510,7 +538,7 @@ bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, margin->set(padx, pady); } dst->fBounds.set(src.fBounds.fLeft - padx, src.fBounds.fTop - pady, - src.fBounds.fRight + padx, src.fBounds.fBottom + pady); + src.fBounds.fRight + padx, src.fBounds.fBottom + pady); dst->fRowBytes = dst->fBounds.width(); dst->fFormat = SkMask::kA8_Format; @@ -651,13 +679,6 @@ static float gaussianIntegral(float x) { return 0.4375f + (-x3 / 6.0f - 3.0f * x2 * 0.25f - 1.125f * x); } -// Compute the size of the array allocated for the profile. - -static int compute_profile_size(SkScalar radius) { - return SkScalarRoundToInt(radius * 3); - -} - /* compute_profile allocates and fills in an array of floating point values between 0 and 255 for the profile signature of a blurred half-plane with the given blur radius. Since we're @@ -669,13 +690,13 @@ static int compute_profile_size(SkScalar radius) { memory returned in profile_out. */ -static void compute_profile(SkScalar radius, unsigned int **profile_out) { - int size = compute_profile_size(radius); +static void compute_profile(SkScalar sigma, unsigned int **profile_out) { + int size = SkScalarCeilToInt(6*sigma); int center = size >> 1; unsigned int *profile = SkNEW_ARRAY(unsigned int, size); - float invr = 1.f/radius; + float invr = 1.f/(2*sigma); profile[0] = 255; for (int x = 1 ; x < size ; ++x) { @@ -705,16 +726,17 @@ static inline unsigned int profile_lookup( unsigned int *profile, int loc, int b } bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, - SkScalar provided_radius, Style style, + SkScalar radius, Style style, SkIPoint *margin, SkMask::CreateMode createMode) { - int profile_size; - - float radius = SkScalarToFloat(SkScalarMul(provided_radius, kBlurRadiusFudgeFactor)); - - // adjust blur radius to match interpretation from boxfilter code - radius = (radius + .5f) * 2.f; + return SkBlurMask::BlurRect(SkBlurMask::ConvertRadiusToSigma(radius), + dst, src, + style, margin, createMode); +} - profile_size = compute_profile_size(radius); +bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, + const SkRect &src, Style style, + SkIPoint *margin, SkMask::CreateMode createMode) { + int profile_size = SkScalarCeilToInt(6*sigma); int pad = profile_size/2; if (margin) { @@ -745,7 +767,7 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, } unsigned int *profile = NULL; - compute_profile(radius, &profile); + compute_profile(sigma, &profile); SkAutoTDeleteArray<unsigned int> ada(profile); size_t dstSize = dst->computeImageSize(); @@ -775,8 +797,8 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, if (profile_size <= sw) { horizontalScanline[x] = profile_lookup(profile, x, dstWidth, w); } else { - float span = float(sw)/radius; - float giX = 1.5f - (x+.5f)/radius; + float span = float(sw)/(2*sigma); + float giX = 1.5f - (x+.5f)/(2*sigma); horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span))); } } @@ -786,8 +808,8 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, if (profile_size <= sh) { profile_y = profile_lookup(profile, y, dstHeight, h); } else { - float span = float(sh)/radius; - float giY = 1.5f - (y+.5f)/radius; + float span = float(sh)/(2*sigma); + float giY = 1.5f - (y+.5f)/(2*sigma); profile_y = (uint8_t) (255 * (gaussianIntegral(giY) - gaussianIntegral(giY + span))); } @@ -834,22 +856,24 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, return true; } +bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar radius, + Style style, SkIPoint* margin) { + return BlurGroundTruth(ConvertRadiusToSigma(radius), dst, src, style, margin); +} // The "simple" blur is a direct implementation of separable convolution with a discrete // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but very // useful for correctness comparisons. -bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar provided_radius, - Style style, SkIPoint* margin) { +bool SkBlurMask::BlurGroundTruth(SkScalar sigma, SkMask* dst, const SkMask& src, + Style style, SkIPoint* margin) { if (src.fFormat != SkMask::kA8_Format) { return false; } - float radius = SkScalarToFloat(SkScalarMul(provided_radius, kBlurRadiusFudgeFactor)); - float stddev = SkScalarToFloat(radius) /2.0f; - float variance = stddev * stddev; + float variance = sigma * sigma; - int windowSize = SkScalarCeil(stddev*4); + int windowSize = SkScalarCeil(sigma*4); // round window size up to nearest odd number windowSize |= 1; diff --git a/src/effects/SkBlurMask.h b/src/effects/SkBlurMask.h index 36d7800014..f49cd129df 100644 --- a/src/effects/SkBlurMask.h +++ b/src/effects/SkBlurMask.h @@ -29,27 +29,37 @@ public: kHigh_Quality //!< three pass box blur (similar to gaussian) }; + static bool BlurRect(SkScalar sigma, SkMask *dst, const SkRect &src, + Style style, + SkIPoint *margin = NULL, + SkMask::CreateMode createMode = + SkMask::kComputeBoundsAndRenderImage_CreateMode); + static bool BoxBlur(SkMask* dst, const SkMask& src, + SkScalar sigma, Style style, Quality quality, + SkIPoint* margin = NULL); + + // the "ground truth" blur does a gaussian convolution; it's slow + // but useful for comparison purposes. + static bool BlurGroundTruth(SkScalar sigma, SkMask* dst, const SkMask& src, + Style style, + SkIPoint* margin = NULL); + + // DEPRECATED - radius-based static bool BlurRect(SkMask *dst, const SkRect &src, SkScalar radius, Style style, SkIPoint *margin = NULL, - SkMask::CreateMode createMode=SkMask::kComputeBoundsAndRenderImage_CreateMode); + SkMask::CreateMode createMode = + SkMask::kComputeBoundsAndRenderImage_CreateMode); + // DEPRECATED - radius-based static bool Blur(SkMask* dst, const SkMask& src, SkScalar radius, Style style, Quality quality, SkIPoint* margin = NULL); - - // the "ground truth" blur does a gaussian convolution; it's slow - // but useful for comparison purposes. - + // DEPRECATED - radius-based static bool BlurGroundTruth(SkMask* dst, const SkMask& src, - SkScalar provided_radius, Style style, - SkIPoint* margin = NULL); - - // scale factor for the blur radius to match the behavior of the all existing blur - // code (both on the CPU and the GPU). This magic constant is 1/sqrt(3). - // TODO: get rid of this fudge factor and move any required fudging up into - // the calling library - static const SkScalar kBlurRadiusFudgeFactor; + SkScalar radius, Style style, + SkIPoint* margin = NULL); + static SkScalar ConvertRadiusToSigma(SkScalar radius); }; #endif diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index b54c33004c..88333582a6 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -24,8 +24,7 @@ class SkBlurMaskFilterImpl : public SkMaskFilter { public: - SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle, - uint32_t flags); + SkBlurMaskFilterImpl(SkScalar sigma, SkBlurMaskFilter::BlurStyle, uint32_t flags); // overrides from SkMaskFilter virtual SkMask::Format getFormat() const SK_OVERRIDE; @@ -60,37 +59,26 @@ private: // To avoid unseemly allocation requests (esp. for finite platforms like // handset) we limit the radius so something manageable. (as opposed to // a request like 10,000) - static const SkScalar kMAX_BLUR_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; - - SkScalar fRadius; + static const SkScalar kMAX_BLUR_SIGMA; + + SkScalar fSigma; SkBlurMaskFilter::BlurStyle fBlurStyle; uint32_t fBlurFlags; SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; -#if SK_SUPPORT_GPU - SkScalar computeXformedRadius(const SkMatrix& ctm) const { + + SkScalar computeXformedSigma(const SkMatrix& ctm) const { bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag); - SkScalar xformedRadius = ignoreTransform ? fRadius - : ctm.mapRadius(fRadius); - return SkMinScalar(xformedRadius, kMAX_BLUR_RADIUS); + SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma); + return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); } -#endif typedef SkMaskFilter INHERITED; }; -const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_RADIUS = SkIntToScalar(128); -const SkScalar SkBlurMaskFilterImpl::kBLUR_SIGMA_SCALE = SkFloatToScalar(0.6f); +const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style, @@ -101,15 +89,29 @@ SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, return NULL; } - return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); + SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); + + return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); +} + +SkMaskFilter* SkBlurMaskFilter::Create(SkBlurMaskFilter::BlurStyle style, + SkScalar sigma, + uint32_t flags) { + // use !(sigma > 0) instead of sigma <= 0 to reject NaN values + if (!(sigma > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount + || flags > SkBlurMaskFilter::kAll_BlurFlag) { + return NULL; + } + + return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); } /////////////////////////////////////////////////////////////////////////////// -SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, +SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurMaskFilter::BlurStyle style, uint32_t flags) - : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) { + : fSigma(sigma), fBlurStyle(style), fBlurFlags(flags) { #if 0 fGamma = NULL; if (gammaScale) { @@ -120,7 +122,7 @@ SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); } #endif - SkASSERT(radius >= 0); + SkASSERT(fSigma >= 0); SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); } @@ -132,35 +134,22 @@ SkMask::Format SkBlurMaskFilterImpl::getFormat() const { bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin) const{ - SkScalar radius; - if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { - radius = fRadius; - } else { - radius = matrix.mapRadius(fRadius); - } + SkScalar sigma = this->computeXformedSigma(matrix); - radius = SkMinScalar(radius, kMAX_BLUR_RADIUS); SkBlurMask::Quality blurQuality = (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; - return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, - blurQuality, margin); + return SkBlurMask::BoxBlur(dst, src, sigma, (SkBlurMask::Style)fBlurStyle, + blurQuality, margin); } bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, const SkMatrix& matrix, SkIPoint* margin, SkMask::CreateMode createMode) const{ - SkScalar radius; - if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { - radius = fRadius; - } else { - radius = matrix.mapRadius(fRadius); - } + SkScalar sigma = computeXformedSigma(matrix); - radius = SkMinScalar(radius, kMAX_BLUR_RADIUS); - - return SkBlurMask::BlurRect(dst, r, radius, (SkBlurMask::Style)fBlurStyle, + return SkBlurMask::BlurRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, margin, createMode); } @@ -334,24 +323,7 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) const { - SkScalar gpuPad, rasterPad; - - { - // GPU path - SkScalar sigma = SkScalarMul(fRadius, kBLUR_SIGMA_SCALE); - gpuPad = sigma * 3.0f; - } - - { - // raster path - SkScalar radius = SkScalarMul(fRadius, SkBlurMask::kBlurRadiusFudgeFactor); - - radius = (radius + .5f) * 2.f; - - rasterPad = SkIntToScalar(SkScalarRoundToInt(radius * 3)/2); - } - - SkScalar pad = SkMaxScalar(gpuPad, rasterPad); + SkScalar pad = 3.0f * fSigma; dst->set(src.fLeft - pad, src.fTop - pad, src.fRight + pad, src.fBottom + pad); @@ -359,16 +331,27 @@ void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : SkMaskFilter(buffer) { - fRadius = buffer.readScalar(); + fSigma = buffer.readScalar(); +#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO + // Fixing this must be done in two stages. When the skps are recaptured in V13, + // remove the ConvertRadiusToSigma but retain the absolute value. + // At the same time, switch the code in flatten to write a positive value. + // When the skps are captured in V14 the absolute value can be removed. + if (fSigma > 0) { + fSigma = SkBlurMask::ConvertRadiusToSigma(fSigma); + } else { + fSigma = -fSigma; + } +#endif fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt(); fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; - SkASSERT(fRadius >= 0); + SkASSERT(fSigma >= 0); SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); } void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); - buffer.writeScalar(fRadius); + buffer.writeScalar(-fSigma); buffer.writeInt(fBlurStyle); buffer.writeUInt(fBlurFlags); } @@ -379,17 +362,17 @@ bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, const SkIRect& clipBounds, const SkMatrix& ctm, SkRect* maskRect) const { - SkScalar xformedRadius = this->computeXformedRadius(ctm); - if (xformedRadius <= 0) { + SkScalar xformedSigma = this->computeXformedSigma(ctm); + if (xformedSigma <= 0) { return false; } - static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); - static const SkScalar kMIN_GPU_BLUR_RADIUS = SkIntToScalar(32); + static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); + static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && srcBounds.height() <= kMIN_GPU_BLUR_SIZE && - xformedRadius <= kMIN_GPU_BLUR_RADIUS) { + xformedSigma <= kMIN_GPU_BLUR_SIGMA) { // We prefer to blur small rect with small radius via CPU. return false; } @@ -399,7 +382,7 @@ bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, return true; } - float sigma3 = 3 * SkScalarToFloat(xformedRadius) * kBLUR_SIGMA_SCALE; + float sigma3 = 3 * SkScalarToFloat(xformedSigma); SkRect clipRect = SkRect::MakeFromIRect(clipBounds); SkRect srcRect(srcBounds); @@ -422,16 +405,14 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, GrContext::AutoWideOpenIdentityDraw awo(context, NULL); - SkScalar xformedRadius = this->computeXformedRadius(context->getMatrix()); - SkASSERT(xformedRadius > 0); - - float sigma = SkScalarToFloat(xformedRadius) * kBLUR_SIGMA_SCALE; + SkScalar xformedSigma = this->computeXformedSigma(context->getMatrix()); + SkASSERT(xformedSigma > 0); // If we're doing a normal blur, we can clobber the pathTexture in the // gaussianBlur. Otherwise, we need to save it for later compositing. bool isNormalBlur = (SkBlurMaskFilter::kNormal_BlurStyle == fBlurStyle); *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOverwriteSrc, - clipRect, false, sigma, sigma); + clipRect, false, xformedSigma, xformedSigma); if (NULL == *result) { return false; } @@ -469,8 +450,8 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, void SkBlurMaskFilterImpl::toString(SkString* str) const { str->append("SkBlurMaskFilterImpl: ("); - str->append("radius: "); - str->appendScalar(fRadius); + str->append("sigma: "); + str->appendScalar(fSigma); str->append(" "); static const char* gStyleName[SkBlurMaskFilter::kBlurStyleCount] = { diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp index 391cba55c4..315b8cbab4 100644 --- a/src/effects/SkEmbossMaskFilter.cpp +++ b/src/effects/SkEmbossMaskFilter.cpp @@ -26,6 +26,12 @@ static inline int pin2byte(int n) { SkMaskFilter* SkBlurMaskFilter::CreateEmboss(const SkScalar direction[3], SkScalar ambient, SkScalar specular, SkScalar blurRadius) { + return SkBlurMaskFilter::CreateEmboss(SkBlurMask::ConvertRadiusToSigma(blurRadius), + direction, ambient, specular); +} + +SkMaskFilter* SkBlurMaskFilter::CreateEmboss(SkScalar blurSigma, const SkScalar direction[3], + SkScalar ambient, SkScalar specular) { if (direction == NULL) { return NULL; } @@ -42,7 +48,7 @@ SkMaskFilter* SkBlurMaskFilter::CreateEmboss(const SkScalar direction[3], light.fAmbient = SkToU8(am); light.fSpecular = SkToU8(sp); - return SkNEW_ARGS(SkEmbossMaskFilter, (light, blurRadius)); + return SkNEW_ARGS(SkEmbossMaskFilter, (blurSigma, light)); } /////////////////////////////////////////////////////////////////////////////// @@ -56,9 +62,16 @@ static void normalize(SkScalar v[3]) { } } +SkEmbossMaskFilter::SkEmbossMaskFilter(SkScalar blurSigma, const Light& light) + : fBlurSigma(blurSigma), fLight(light) { + normalize(fLight.fDirection); +} + SkEmbossMaskFilter::SkEmbossMaskFilter(const Light& light, SkScalar blurRadius) - : fLight(light), fBlurRadius(blurRadius) { + : fLight(light) { normalize(fLight.fDirection); + + fBlurSigma = SkBlurMask::ConvertRadiusToSigma(blurRadius); } SkMask::Format SkEmbossMaskFilter::getFormat() const { @@ -66,17 +79,17 @@ SkMask::Format SkEmbossMaskFilter::getFormat() const { } bool SkEmbossMaskFilter::filterMask(SkMask* dst, const SkMask& src, - const SkMatrix& matrix, SkIPoint* margin) const { - SkScalar radius = matrix.mapRadius(fBlurRadius); + const SkMatrix& matrix, SkIPoint* margin) const { + SkScalar sigma = matrix.mapRadius(fBlurSigma); - if (!SkBlurMask::Blur(dst, src, radius, SkBlurMask::kInner_Style, - SkBlurMask::kLow_Quality)) { + if (!SkBlurMask::BoxBlur(dst, src, sigma, SkBlurMask::kInner_Style, + SkBlurMask::kLow_Quality)) { return false; } dst->fFormat = SkMask::k3D_Format; if (margin) { - margin->set(SkScalarCeil(radius), SkScalarCeil(radius)); + margin->set(SkScalarCeil(3*sigma), SkScalarCeil(3*sigma)); } if (src.fImage == NULL) { @@ -121,7 +134,18 @@ SkEmbossMaskFilter::SkEmbossMaskFilter(SkFlattenableReadBuffer& buffer) SkASSERT(buffer.getArrayCount() == sizeof(Light)); buffer.readByteArray(&fLight); SkASSERT(fLight.fPad == 0); // for the font-cache lookup to be clean - fBlurRadius = buffer.readScalar(); + fBlurSigma = buffer.readScalar(); +#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO + // Fixing this must be done in two stages. When the skps are recaptured in V13, + // remove the ConvertRadiusToSigma but retain the absolute value. + // At the same time, switch the code in flatten to write a positive value. + // When the skps are captured in V14 the absolute value can be removed. + if (fBlurSigma > 0) { + fBlurSigma = SkBlurMask::ConvertRadiusToSigma(fBlurSigma); + } else { + fBlurSigma = -fBlurSigma; + } +#endif } void SkEmbossMaskFilter::flatten(SkFlattenableWriteBuffer& buffer) const { @@ -130,7 +154,7 @@ void SkEmbossMaskFilter::flatten(SkFlattenableWriteBuffer& buffer) const { Light tmpLight = fLight; tmpLight.fPad = 0; // for the font-cache lookup to be clean buffer.writeByteArray(&tmpLight, sizeof(tmpLight)); - buffer.writeScalar(fBlurRadius); + buffer.writeScalar(-fBlurSigma); } #ifdef SK_DEVELOPER @@ -148,8 +172,8 @@ void SkEmbossMaskFilter::toString(SkString* str) const { str->appendf("ambient: %d specular: %d ", fLight.fAmbient, fLight.fSpecular); - str->append("blurRadius: "); - str->appendScalar(fBlurRadius); + str->append("blurSigma: "); + str->appendScalar(fBlurSigma); str->append(")"); } #endif |