| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkAlphaThresholdFilter.h" | 8 #include "SkAlphaThresholdFilter.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkImagePriv.h" |
| 10 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
| 11 #include "SkWriteBuffer.h" | 12 #include "SkWriteBuffer.h" |
| 12 #include "SkRegion.h" | 13 #include "SkRegion.h" |
| 13 | 14 |
| 14 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter { | 15 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter { |
| 15 public: | 16 public: |
| 16 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold, | 17 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold, |
| 17 SkScalar outerThreshold, SkImageFilter* input); | 18 SkScalar outerThreshold, SkImageFilter* input); |
| 18 | 19 |
| 19 SK_TO_STRING_OVERRIDE() | 20 SK_TO_STRING_OVERRIDE() |
| 20 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterIm
pl) | 21 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterIm
pl) |
| 21 | 22 |
| 22 protected: | 23 protected: |
| 23 void flatten(SkWriteBuffer&) const SK_OVERRIDE; | 24 void flatten(SkWriteBuffer&) const SK_OVERRIDE; |
| 24 | 25 |
| 25 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, | 26 virtual bool onFilterImage(Proxy*, const SkImage* src, const Context&, |
| 26 SkBitmap* result, SkIPoint* offset) const SK_OVER
RIDE; | 27 SkAutoTUnref<const SkImage>& result, |
| 28 SkIPoint* offset) const SK_OVERRIDE; |
| 27 #if SK_SUPPORT_GPU | 29 #if SK_SUPPORT_GPU |
| 28 virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const Sk
Matrix&, | 30 virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const Sk
Matrix&, |
| 29 const SkIRect& bounds) const SK_OVERRIDE; | 31 const SkIRect& bounds) const SK_OVERRIDE; |
| 30 #endif | 32 #endif |
| 31 | 33 |
| 32 private: | 34 private: |
| 33 SkRegion fRegion; | 35 SkRegion fRegion; |
| 34 SkScalar fInnerThreshold; | 36 SkScalar fInnerThreshold; |
| 35 SkScalar fOuterThreshold; | 37 SkScalar fOuterThreshold; |
| 36 typedef SkImageFilter INHERITED; | 38 typedef SkImageFilter INHERITED; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 } | 287 } |
| 286 | 288 |
| 287 { | 289 { |
| 288 GrPaint grPaint; | 290 GrPaint grPaint; |
| 289 grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 291 grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
| 290 SkRegion::Iterator iter(fRegion); | 292 SkRegion::Iterator iter(fRegion); |
| 291 context->clear(NULL, 0x0, true, maskTexture->asRenderTarget()); | 293 context->clear(NULL, 0x0, true, maskTexture->asRenderTarget()); |
| 292 | 294 |
| 293 while (!iter.done()) { | 295 while (!iter.done()) { |
| 294 SkRect rect = SkRect::Make(iter.rect()); | 296 SkRect rect = SkRect::Make(iter.rect()); |
| 295 context->drawRect(maskTexture->asRenderTarget(), GrClip::WideOpe
n(), grPaint, | 297 context->drawRect(maskRT, GrClip::WideOpen(), grPaint, in_matrix
, rect); |
| 296 in_matrix, rect); | |
| 297 iter.next(); | 298 iter.next(); |
| 298 } | 299 } |
| 299 } | 300 } |
| 300 | 301 |
| 301 *fp = AlphaThresholdEffect::Create(texture, | 302 *fp = AlphaThresholdEffect::Create(texture, |
| 302 maskTexture, | 303 maskTexture, |
| 303 fInnerThreshold, | 304 fInnerThreshold, |
| 304 fOuterThreshold); | 305 fOuterThreshold); |
| 305 } | 306 } |
| 306 return true; | 307 return true; |
| 307 } | 308 } |
| 308 #endif | 309 #endif |
| 309 | 310 |
| 310 void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const { | 311 void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const { |
| 311 this->INHERITED::flatten(buffer); | 312 this->INHERITED::flatten(buffer); |
| 312 buffer.writeScalar(fInnerThreshold); | 313 buffer.writeScalar(fInnerThreshold); |
| 313 buffer.writeScalar(fOuterThreshold); | 314 buffer.writeScalar(fOuterThreshold); |
| 314 buffer.writeRegion(fRegion); | 315 buffer.writeRegion(fRegion); |
| 315 } | 316 } |
| 316 | 317 |
| 317 bool SkAlphaThresholdFilterImpl::onFilterImage(Proxy*, const SkBitmap& src, | 318 bool SkAlphaThresholdFilterImpl::onFilterImage(Proxy*, const SkImage* src, |
| 318 const Context& ctx, SkBitmap* dst
, | 319 const Context& ctx, SkAutoTUnref<
const SkImage>& dst, |
| 319 SkIPoint* offset) const { | 320 SkIPoint* offset) const { |
| 320 SkASSERT(src.colorType() == kN32_SkColorType); | |
| 321 | |
| 322 if (src.colorType() != kN32_SkColorType) { | |
| 323 return false; | |
| 324 } | |
| 325 | |
| 326 SkMatrix localInverse; | 321 SkMatrix localInverse; |
| 327 if (!ctx.ctm().invert(&localInverse)) { | 322 if (!ctx.ctm().invert(&localInverse)) { |
| 328 return false; | 323 return false; |
| 329 } | 324 } |
| 330 | 325 |
| 331 SkAutoLockPixels alp(src); | 326 SkBitmap srcBitmap; |
| 332 SkASSERT(src.getPixels()); | 327 SkAutoImageAsN32Bitmap aai(src, &srcBitmap); |
| 333 if (!src.getPixels() || src.width() <= 0 || src.height() <= 0) { | 328 if (!srcBitmap.getPixels() || srcBitmap.width() <= 0 || srcBitmap.height() <
= 0) { |
| 334 return false; | 329 return false; |
| 335 } | 330 } |
| 336 | 331 |
| 337 if (!dst->tryAllocPixels(src.info())) { | 332 SkBitmap dstBitmap; |
| 333 if (!dstBitmap.tryAllocPixels(srcBitmap.info())) { |
| 338 return false; | 334 return false; |
| 339 } | 335 } |
| 340 | 336 |
| 341 U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF); | 337 U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF); |
| 342 U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF); | 338 U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF); |
| 343 SkColor* sptr = src.getAddr32(0, 0); | 339 SkColor* sptr = srcBitmap.getAddr32(0, 0); |
| 344 SkColor* dptr = dst->getAddr32(0, 0); | 340 SkColor* dptr = dstBitmap.getAddr32(0, 0); |
| 345 int width = src.width(), height = src.height(); | 341 int width = srcBitmap.width(), height = srcBitmap.height(); |
| 346 for (int y = 0; y < height; ++y) { | 342 for (int y = 0; y < height; ++y) { |
| 347 for (int x = 0; x < width; ++x) { | 343 for (int x = 0; x < width; ++x) { |
| 348 const SkColor& source = sptr[y * width + x]; | 344 const SkColor& source = sptr[y * width + x]; |
| 349 SkColor output_color(source); | 345 SkColor output_color(source); |
| 350 SkPoint position; | 346 SkPoint position; |
| 351 localInverse.mapXY((SkScalar)x, (SkScalar)y, &position); | 347 localInverse.mapXY((SkScalar)x, (SkScalar)y, &position); |
| 352 if (fRegion.contains((int32_t)position.x(), (int32_t)position.y()))
{ | 348 if (fRegion.contains((int32_t)position.x(), (int32_t)position.y()))
{ |
| 353 if (SkColorGetA(source) < innerThreshold) { | 349 if (SkColorGetA(source) < innerThreshold) { |
| 354 U8CPU alpha = SkColorGetA(source); | 350 U8CPU alpha = SkColorGetA(source); |
| 355 if (alpha == 0) | 351 if (alpha == 0) |
| 356 alpha = 1; | 352 alpha = 1; |
| 357 float scale = (float)innerThreshold / alpha; | 353 float scale = (float)innerThreshold / alpha; |
| 358 output_color = SkColorSetARGB(innerThreshold, | 354 output_color = SkColorSetARGB(innerThreshold, |
| 359 (U8CPU)(SkColorGetR(source) *
scale), | 355 (U8CPU)(SkColorGetR(source) *
scale), |
| 360 (U8CPU)(SkColorGetG(source) *
scale), | 356 (U8CPU)(SkColorGetG(source) *
scale), |
| 361 (U8CPU)(SkColorGetB(source) *
scale)); | 357 (U8CPU)(SkColorGetB(source) *
scale)); |
| 362 } | 358 } |
| 363 } else { | 359 } else { |
| 364 if (SkColorGetA(source) > outerThreshold) { | 360 if (SkColorGetA(source) > outerThreshold) { |
| 365 float scale = (float)outerThreshold / SkColorGetA(source); | 361 float scale = (float)outerThreshold / SkColorGetA(source); |
| 366 output_color = SkColorSetARGB(outerThreshold, | 362 output_color = SkColorSetARGB(outerThreshold, |
| 367 (U8CPU)(SkColorGetR(source) *
scale), | 363 (U8CPU)(SkColorGetR(source) *
scale), |
| 368 (U8CPU)(SkColorGetG(source) *
scale), | 364 (U8CPU)(SkColorGetG(source) *
scale), |
| 369 (U8CPU)(SkColorGetB(source) *
scale)); | 365 (U8CPU)(SkColorGetB(source) *
scale)); |
| 370 } | 366 } |
| 371 } | 367 } |
| 372 dptr[y * dst->width() + x] = output_color; | 368 dptr[y * dstBitmap.width() + x] = output_color; |
| 373 } | 369 } |
| 374 } | 370 } |
| 371 srcBitmap = SkBitmap(); |
| 375 | 372 |
| 373 SkImage* image = SkNewImageFromBitmap(dstBitmap, NULL); |
| 374 if (NULL == image) { |
| 375 return false; |
| 376 } |
| 377 dst.reset(image); |
| 378 offset->fX = 0; |
| 379 offset->fY = 0; |
| 376 return true; | 380 return true; |
| 377 } | 381 } |
| 378 | 382 |
| 379 #ifndef SK_IGNORE_TO_STRING | 383 #ifndef SK_IGNORE_TO_STRING |
| 380 void SkAlphaThresholdFilterImpl::toString(SkString* str) const { | 384 void SkAlphaThresholdFilterImpl::toString(SkString* str) const { |
| 381 str->appendf("SkAlphaThresholdImageFilter: ("); | 385 str->appendf("SkAlphaThresholdImageFilter: ("); |
| 382 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold); | 386 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold); |
| 383 str->append(")"); | 387 str->append(")"); |
| 384 } | 388 } |
| 385 #endif | 389 #endif |
| 386 | 390 |
| OLD | NEW |