| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkBlurMaskFilter.h" | 9 #include "SkBlurMaskFilter.h" |
| 10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa
trix&, | 62 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa
trix&, |
| 63 const SkIRect& clipBounds, | 63 const SkIRect& clipBounds, |
| 64 NinePatch*) const SK_OVERRIDE; | 64 NinePatch*) const SK_OVERRIDE; |
| 65 | 65 |
| 66 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, | 66 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, |
| 67 const SkIRect& clipBounds, | 67 const SkIRect& clipBounds, |
| 68 NinePatch*) const SK_OVERRIDE; | 68 NinePatch*) const SK_OVERRIDE; |
| 69 | 69 |
| 70 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, | 70 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, |
| 71 SkIPoint* margin, SkMask::CreateMode createMode) const; | 71 SkIPoint* margin, SkMask::CreateMode createMode) const; |
| 72 bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, |
| 73 SkIPoint* margin, SkMask::CreateMode createMode) const; |
| 72 | 74 |
| 73 private: | 75 private: |
| 74 // To avoid unseemly allocation requests (esp. for finite platforms like | 76 // To avoid unseemly allocation requests (esp. for finite platforms like |
| 75 // handset) we limit the radius so something manageable. (as opposed to | 77 // handset) we limit the radius so something manageable. (as opposed to |
| 76 // a request like 10,000) | 78 // a request like 10,000) |
| 77 static const SkScalar kMAX_BLUR_SIGMA; | 79 static const SkScalar kMAX_BLUR_SIGMA; |
| 78 | 80 |
| 79 SkScalar fSigma; | 81 SkScalar fSigma; |
| 80 SkBlurMaskFilter::BlurStyle fBlurStyle; | 82 SkBlurMaskFilter::BlurStyle fBlurStyle; |
| 81 uint32_t fBlurFlags; | 83 uint32_t fBlurFlags; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 163 |
| 162 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, | 164 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, |
| 163 const SkMatrix& matrix, | 165 const SkMatrix& matrix, |
| 164 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ | 166 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
| 165 SkScalar sigma = computeXformedSigma(matrix); | 167 SkScalar sigma = computeXformedSigma(matrix); |
| 166 | 168 |
| 167 return SkBlurMask::BlurRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, | 169 return SkBlurMask::BlurRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, |
| 168 margin, createMode); | 170 margin, createMode); |
| 169 } | 171 } |
| 170 | 172 |
| 173 bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, |
| 174 const SkMatrix& matrix, |
| 175 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
| 176 SkScalar sigma = computeXformedSigma(matrix); |
| 177 |
| 178 return SkBlurMask::BlurRRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, |
| 179 margin, createMode); |
| 180 } |
| 181 |
| 171 #include "SkCanvas.h" | 182 #include "SkCanvas.h" |
| 172 | 183 |
| 173 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { | 184 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { |
| 174 SkASSERT(mask != NULL); | 185 SkASSERT(mask != NULL); |
| 175 | 186 |
| 176 bounds.roundOut(&mask->fBounds); | 187 bounds.roundOut(&mask->fBounds); |
| 177 mask->fRowBytes = SkAlign4(mask->fBounds.width()); | 188 mask->fRowBytes = SkAlign4(mask->fBounds.width()); |
| 178 mask->fFormat = SkMask::kA8_Format; | 189 mask->fFormat = SkMask::kA8_Format; |
| 179 const size_t size = mask->computeImageSize(); | 190 const size_t size = mask->computeImageSize(); |
| 180 mask->fImage = SkMask::AllocImage(size); | 191 mask->fImage = SkMask::AllocImage(size); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 canvas.drawPath(path, paint); | 248 canvas.drawPath(path, paint); |
| 238 } | 249 } |
| 239 return true; | 250 return true; |
| 240 } | 251 } |
| 241 | 252 |
| 242 static bool rect_exceeds(const SkRect& r, SkScalar v) { | 253 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
| 243 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || | 254 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || |
| 244 r.width() > v || r.height() > v; | 255 r.width() > v || r.height() > v; |
| 245 } | 256 } |
| 246 | 257 |
| 258 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
| 259 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", fa
lse, "Use the faster analytic blur approach for ninepatch rects" ); |
| 260 #else |
| 261 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", tr
ue, "Use the faster analytic blur approach for ninepatch round rects" ); |
| 262 #endif |
| 263 |
| 247 SkMaskFilter::FilterReturn | 264 SkMaskFilter::FilterReturn |
| 248 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, | 265 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, |
| 249 const SkIRect& clipBounds, | 266 const SkIRect& clipBounds, |
| 250 NinePatch* patch) const { | 267 NinePatch* patch) const { |
| 251 SkASSERT(patch != NULL); | 268 SkASSERT(patch != NULL); |
| 252 switch (rrect.getType()) { | 269 switch (rrect.getType()) { |
| 253 case SkRRect::kUnknown_Type: | 270 case SkRRect::kUnknown_Type: |
| 254 // Unknown should never be returned. | 271 // Unknown should never be returned. |
| 255 SkASSERT(false); | 272 SkASSERT(false); |
| 256 // Fall through. | 273 // Fall through. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 286 return kUnimplemented_FilterReturn; | 303 return kUnimplemented_FilterReturn; |
| 287 } | 304 } |
| 288 | 305 |
| 289 SkIPoint margin; | 306 SkIPoint margin; |
| 290 SkMask srcM, dstM; | 307 SkMask srcM, dstM; |
| 291 rrect.rect().roundOut(&srcM.fBounds); | 308 rrect.rect().roundOut(&srcM.fBounds); |
| 292 srcM.fImage = NULL; | 309 srcM.fImage = NULL; |
| 293 srcM.fFormat = SkMask::kA8_Format; | 310 srcM.fFormat = SkMask::kA8_Format; |
| 294 srcM.fRowBytes = 0; | 311 srcM.fRowBytes = 0; |
| 295 | 312 |
| 296 if (!this->filterMask(&dstM, srcM, matrix, &margin)) { | 313 bool filterResult = false; |
| 314 if (c_analyticBlurRRect) { |
| 315 // special case for fast round rect blur |
| 316 // don't actually do the blur the first time, just compute the correct s
ize |
| 317 filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, |
| 318 SkMask::kJustComputeBounds_CreateMod
e); |
| 319 } |
| 320 |
| 321 if (!filterResult) { |
| 322 filterResult = this->filterMask(&dstM, srcM, matrix, &margin); |
| 323 } |
| 324 |
| 325 if (!filterResult) { |
| 297 return kFalse_FilterReturn; | 326 return kFalse_FilterReturn; |
| 298 } | 327 } |
| 299 | 328 |
| 300 // Now figure out the appropriate width and height of the smaller round rect
angle | 329 // Now figure out the appropriate width and height of the smaller round rect
angle |
| 301 // to stretch. It will take into account the larger radius per side as well
as double | 330 // to stretch. It will take into account the larger radius per side as well
as double |
| 302 // the margin, to account for inner and outer blur. | 331 // the margin, to account for inner and outer blur. |
| 303 const SkVector& UL = rrect.radii(SkRRect::kUpperLeft_Corner); | 332 const SkVector& UL = rrect.radii(SkRRect::kUpperLeft_Corner); |
| 304 const SkVector& UR = rrect.radii(SkRRect::kUpperRight_Corner); | 333 const SkVector& UR = rrect.radii(SkRRect::kUpperRight_Corner); |
| 305 const SkVector& LR = rrect.radii(SkRRect::kLowerRight_Corner); | 334 const SkVector& LR = rrect.radii(SkRRect::kLowerRight_Corner); |
| 306 const SkVector& LL = rrect.radii(SkRRect::kLowerLeft_Corner); | 335 const SkVector& LL = rrect.radii(SkRRect::kLowerLeft_Corner); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 330 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); | 359 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); |
| 331 | 360 |
| 332 SkRRect smallRR; | 361 SkRRect smallRR; |
| 333 SkVector radii[4]; | 362 SkVector radii[4]; |
| 334 radii[SkRRect::kUpperLeft_Corner] = UL; | 363 radii[SkRRect::kUpperLeft_Corner] = UL; |
| 335 radii[SkRRect::kUpperRight_Corner] = UR; | 364 radii[SkRRect::kUpperRight_Corner] = UR; |
| 336 radii[SkRRect::kLowerRight_Corner] = LR; | 365 radii[SkRRect::kLowerRight_Corner] = LR; |
| 337 radii[SkRRect::kLowerLeft_Corner] = LL; | 366 radii[SkRRect::kLowerLeft_Corner] = LL; |
| 338 smallRR.setRectRadii(smallR, radii); | 367 smallRR.setRectRadii(smallR, radii); |
| 339 | 368 |
| 340 if (!draw_rrect_into_mask(smallRR, &srcM)) { | 369 bool analyticBlurWorked = false; |
| 341 return kFalse_FilterReturn; | 370 if (c_analyticBlurRRect) { |
| 371 analyticBlurWorked = |
| 372 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
| 373 SkMask::kComputeBoundsAndRenderImage_CreateMod
e); |
| 342 } | 374 } |
| 343 | 375 |
| 344 SkAutoMaskFreeImage amf(srcM.fImage); | 376 if (!analyticBlurWorked) { |
| 377 if (!draw_rrect_into_mask(smallRR, &srcM)) { |
| 378 return kFalse_FilterReturn; |
| 379 } |
| 345 | 380 |
| 346 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 381 SkAutoMaskFreeImage amf(srcM.fImage); |
| 347 return kFalse_FilterReturn; | 382 |
| 383 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
| 384 return kFalse_FilterReturn; |
| 385 } |
| 348 } | 386 } |
| 349 | 387 |
| 350 patch->fMask.fBounds.offsetTo(0, 0); | 388 patch->fMask.fBounds.offsetTo(0, 0); |
| 351 patch->fOuterRect = dstM.fBounds; | 389 patch->fOuterRect = dstM.fBounds; |
| 352 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 390 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| 353 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 391 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| 354 return kTrue_FilterReturn; | 392 return kTrue_FilterReturn; |
| 355 } | 393 } |
| 356 | 394 |
| 357 #ifdef SK_IGNORE_FAST_RECT_BLUR | 395 #ifdef SK_IGNORE_FAST_RECT_BLUR |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 } else { | 933 } else { |
| 896 str->append("None"); | 934 str->append("None"); |
| 897 } | 935 } |
| 898 str->append("))"); | 936 str->append("))"); |
| 899 } | 937 } |
| 900 #endif | 938 #endif |
| 901 | 939 |
| 902 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 940 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 903 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 941 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 904 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 942 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |