Index: src/effects/SkBlurMask.cpp |
diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp |
index 413e8c0690311238dbc17b02f6568b1a0c732c61..d63de8c8c288c4a3e61c204d4e3e06214626af48 100644 |
--- a/src/effects/SkBlurMask.cpp |
+++ b/src/effects/SkBlurMask.cpp |
@@ -1200,20 +1200,22 @@ static float gaussianIntegral(float x) { |
static int compute_profile(SkScalar radius, unsigned int **profile_out) { |
int size = SkScalarRoundToInt(radius * 3); |
- int center = size >> 1; |
- |
- unsigned int *profile = SkNEW_ARRAY(unsigned int, size); |
- |
- float invr = 1.f/radius; |
+ |
+ if (profile_out) { |
+ int center = size >> 1; |
+ unsigned int *profile = SkNEW_ARRAY(unsigned int, size); |
+ |
+ float invr = 1.f/radius; |
+ |
+ profile[0] = 255; |
+ for (int x = 1 ; x < size ; ++x) { |
+ float scaled_x = (center - x - .5f) * invr; |
+ float gi = gaussianIntegral(scaled_x); |
+ profile[x] = 255 - (uint8_t) (255.f * gi); |
+ } |
- profile[0] = 255; |
- for (int x = 1 ; x < size ; ++x) { |
- float scaled_x = (center - x - .5f) * invr; |
- float gi = gaussianIntegral(scaled_x); |
- profile[x] = 255 - (uint8_t) (255.f * gi); |
+ *profile_out = profile; |
} |
- |
- *profile_out = profile; |
return size; |
} |
@@ -1236,16 +1238,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, bool perform_blur) { |
int profile_size; |
- unsigned int *profile; |
+ unsigned int *profile = NULL; |
float radius = SkScalarToFloat( SkScalarMul( provided_radius, kBlurRadiusFudgeFactor ) ); |
// adjust blur radius to match interpretation from boxfilter code |
radius = (radius + .5f) *2.f; |
bungeman-skia
2013/03/11 19:47:41
My eyes... need a space after *
|
- profile_size = compute_profile( radius, &profile ); |
+ profile_size = compute_profile( radius, perform_blur ? &profile : NULL ); |
bungeman-skia
2013/03/11 19:47:41
It feels awkward to have this check here and anoth
|
SkAutoTDeleteArray<unsigned int> ada(profile); |
@@ -1259,89 +1261,96 @@ 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); |
bungeman-skia
2013/03/11 19:47:41
Nit: This line got really long. A few more below.
|
dst->fRowBytes = dst->fBounds.width(); |
dst->fFormat = SkMask::kA8_Format; |
dst->fImage = NULL; |
- |
- 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()); |
+ |
+ if (perform_blur) { |
bungeman-skia
2013/03/11 19:47:41
Can we put the else clause under !perform_blur and
|
+ size_t dstSize = dst->computeImageSize(); |
+ if (0 == dstSize) { |
+ return false; // too big to allocate, abort |
+ } |
- uint8_t* dp = SkMask::AllocImage(dstSize); |
+ uint8_t* dp = SkMask::AllocImage(dstSize); |
- dst->fImage = dp; |
+ dst->fImage = dp; |
- int dstHeight = dst->fBounds.height(); |
- int dstWidth = dst->fBounds.width(); |
+ int dstHeight = dst->fBounds.height(); |
+ int dstWidth = dst->fBounds.width(); |
- // nearest odd number less than the profile size represents the center |
- // of the (2x scaled) profile |
- int center = ( profile_size & ~1 ) - 1; |
+ // nearest odd number less than the profile size represents the center |
+ // of the (2x scaled) profile |
+ int center = ( profile_size & ~1 ) - 1; |
- int w = sw - center; |
- int h = sh - center; |
+ int w = sw - center; |
+ int h = sh - center; |
- uint8_t *outptr = dp; |
+ uint8_t *outptr = dp; |
- SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth); |
+ SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth); |
- for (int x = 0 ; x < dstWidth ; ++x) { |
- 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; |
- horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span))); |
+ for (int x = 0 ; x < dstWidth ; ++x) { |
+ 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; |
+ horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span))); |
+ } |
} |
- } |
- for (int y = 0 ; y < dstHeight ; ++y) { |
- unsigned int profile_y; |
- 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; |
- profile_y = (uint8_t) (255 * (gaussianIntegral(giY) - gaussianIntegral(giY + span))); |
- } |
+ for (int y = 0 ; y < dstHeight ; ++y) { |
+ unsigned int profile_y; |
+ 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; |
+ profile_y = (uint8_t) (255 * (gaussianIntegral(giY) - gaussianIntegral(giY + span))); |
+ } |
- for (int x = 0 ; x < dstWidth ; x++) { |
- unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], profile_y); |
- *(outptr++) = maskval; |
+ for (int x = 0 ; x < dstWidth ; x++) { |
+ unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], profile_y); |
+ *(outptr++) = maskval; |
+ } |
} |
- } |
- if (style == kInner_Style) { |
- // now we allocate the "real" dst, mirror the size of src |
- size_t srcSize = (size_t)(src.width() * src.height()); |
- if (0 == srcSize) { |
- return false; // too big to allocate, abort |
- } |
- dst->fImage = SkMask::AllocImage(srcSize); |
- for (int y = 0 ; y < sh ; y++) { |
- uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad; |
- uint8_t *inner_scanline = dst->fImage + y*sw; |
- memcpy(inner_scanline, blur_scanline, sw); |
- } |
- SkMask::FreeImage(dp); |
+ if (style == kInner_Style) { |
+ // now we allocate the "real" dst, mirror the size of src |
+ size_t srcSize = (size_t)(src.width() * src.height()); |
+ if (0 == srcSize) { |
+ return false; // too big to allocate, abort |
+ } |
+ dst->fImage = SkMask::AllocImage(srcSize); |
+ for (int y = 0 ; y < sh ; y++) { |
+ uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad; |
+ uint8_t *inner_scanline = dst->fImage + y*sw; |
+ memcpy(inner_scanline, blur_scanline, sw); |
+ } |
+ SkMask::FreeImage(dp); |
- dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds |
- dst->fRowBytes = sw; |
+ dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds |
+ dst->fRowBytes = sw; |
- } else if (style == kOuter_Style) { |
- for (int y = pad ; y < dstHeight-pad ; y++) { |
- uint8_t *dst_scanline = dp + y*dstWidth + pad; |
- memset(dst_scanline, 0, sw); |
+ } else if (style == kOuter_Style) { |
+ for (int y = pad ; y < dstHeight-pad ; y++) { |
+ uint8_t *dst_scanline = dp + y*dstWidth + pad; |
+ memset(dst_scanline, 0, sw); |
+ } |
+ } |
+ // normal and solid styles are the same for analytic rect blurs, so don't |
+ // need to handle solid specially. |
+ } else { |
+ if (style == kInner_Style) { |
+ dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds |
+ dst->fRowBytes = sw; |
} |
} |
- // normal and solid styles are the same for analytic rect blurs, so don't |
- // need to handle solid specially. |
return true; |
} |