| Index: src/effects/SkBlurMask.cpp
|
| diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
|
| index 413e8c0690311238dbc17b02f6568b1a0c732c61..ce440073a0585daeee98f2b7498ee778cc207313 100644
|
| --- a/src/effects/SkBlurMask.cpp
|
| +++ b/src/effects/SkBlurMask.cpp
|
| @@ -1185,6 +1185,15 @@ 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
|
| @@ -1193,15 +1202,14 @@ static float gaussianIntegral(float x) {
|
| all the time, we actually fill in the profile pre-inverted
|
| (already done 255-x).
|
|
|
| - The function returns the size of the array allocated for the
|
| - profile. It's the responsibility of the caller to delete the
|
| + It's the responsibility of the caller to delete the
|
| memory returned in profile_out.
|
| */
|
|
|
| -static int compute_profile(SkScalar radius, unsigned int **profile_out) {
|
| - int size = SkScalarRoundToInt(radius * 3);
|
| +static void compute_profile(SkScalar radius, unsigned int **profile_out) {
|
| + int size = compute_profile_size(radius);
|
| +
|
| int center = size >> 1;
|
| -
|
| unsigned int *profile = SkNEW_ARRAY(unsigned int, size);
|
|
|
| float invr = 1.f/radius;
|
| @@ -1214,7 +1222,6 @@ static int compute_profile(SkScalar radius, unsigned int **profile_out) {
|
| }
|
|
|
| *profile_out = profile;
|
| - return size;
|
| }
|
|
|
| // TODO MAYBE: Maintain a profile cache to avoid recomputing this for
|
| @@ -1236,19 +1243,16 @@ 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,
|
| - SkIPoint *margin) {
|
| + SkIPoint *margin, SkMask::CreateMode createMode) {
|
| int profile_size;
|
| - unsigned int *profile;
|
|
|
| - float radius = SkScalarToFloat( SkScalarMul( provided_radius, kBlurRadiusFudgeFactor ) );
|
| + float radius = SkScalarToFloat(SkScalarMul(provided_radius, kBlurRadiusFudgeFactor));
|
|
|
| // adjust blur radius to match interpretation from boxfilter code
|
| - radius = (radius + .5f) *2.f;
|
| -
|
| - profile_size = compute_profile( radius, &profile );
|
| -
|
| - SkAutoTDeleteArray<unsigned int> ada(profile);
|
| + radius = (radius + .5f) * 2.f;
|
|
|
| + profile_size = compute_profile_size(radius);
|
| +
|
| int pad = profile_size/2;
|
| if (margin) {
|
| margin->set( pad, pad );
|
| @@ -1259,20 +1263,35 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src,
|
| int shadow_right = (int)(src.width()) + pad;
|
| int shadow_bottom = (int)(src.height()) + pad;
|
|
|
| - dst->fBounds.set(shadow_left, shadow_top, shadow_right, shadow_bottom);
|
| + dst->fBounds.set(shadow_left + src.fLeft,
|
| + shadow_top + src.fTop,
|
| + shadow_right + src.fRight,
|
| + shadow_bottom + src.fBottom);
|
|
|
| dst->fRowBytes = dst->fBounds.width();
|
| dst->fFormat = SkMask::kA8_Format;
|
| dst->fImage = NULL;
|
| -
|
| +
|
| + int sw = SkScalarFloorToInt(src.width());
|
| + int sh = SkScalarFloorToInt(src.height());
|
| +
|
| + if (createMode == SkMask::kJustComputeBounds_CreateMode) {
|
| + if (style == kInner_Style) {
|
| + dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds
|
| + dst->fRowBytes = sw;
|
| + }
|
| + return true;
|
| + }
|
| + unsigned int *profile = NULL;
|
| +
|
| + compute_profile(radius, &profile);
|
| + SkAutoTDeleteArray<unsigned int> ada(profile);
|
| +
|
| size_t dstSize = dst->computeImageSize();
|
| if (0 == dstSize) {
|
| return false; // too big to allocate, abort
|
| }
|
|
|
| - int sw = SkScalarFloorToInt(src.width());
|
| - int sh = SkScalarFloorToInt(src.height());
|
| -
|
| uint8_t* dp = SkMask::AllocImage(dstSize);
|
|
|
| dst->fImage = dp;
|
|
|