| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2008 The Android Open Source Project | 2  * Copyright 2008 The Android Open Source Project | 
| 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 "SkCanvas.h" | 8 #include "SkCanvas.h" | 
| 9 #include "SkCanvasPriv.h" | 9 #include "SkCanvasPriv.h" | 
| 10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" | 
| 11 #include "SkColorFilter.h" |  | 
| 12 #include "SkDeviceImageFilterProxy.h" | 11 #include "SkDeviceImageFilterProxy.h" | 
| 13 #include "SkDraw.h" | 12 #include "SkDraw.h" | 
| 14 #include "SkDrawable.h" | 13 #include "SkDrawable.h" | 
| 15 #include "SkDrawFilter.h" | 14 #include "SkDrawFilter.h" | 
| 16 #include "SkDrawLooper.h" | 15 #include "SkDrawLooper.h" | 
| 17 #include "SkErrorInternals.h" | 16 #include "SkErrorInternals.h" | 
| 18 #include "SkImage.h" | 17 #include "SkImage.h" | 
| 19 #include "SkMetaData.h" | 18 #include "SkMetaData.h" | 
| 20 #include "SkPathOps.h" | 19 #include "SkPathOps.h" | 
| 21 #include "SkPatchUtils.h" | 20 #include "SkPatchUtils.h" | 
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 277     SkCanvas*       fCanvas; | 276     SkCanvas*       fCanvas; | 
| 278     const DeviceCM* fCurrLayer; | 277     const DeviceCM* fCurrLayer; | 
| 279     const SkPaint*  fPaint;     // May be null. | 278     const SkPaint*  fPaint;     // May be null. | 
| 280     SkBool8         fSkipEmptyClips; | 279     SkBool8         fSkipEmptyClips; | 
| 281 | 280 | 
| 282     typedef SkDraw INHERITED; | 281     typedef SkDraw INHERITED; | 
| 283 }; | 282 }; | 
| 284 | 283 | 
| 285 ///////////////////////////////////////////////////////////////////////////// | 284 ///////////////////////////////////////////////////////////////////////////// | 
| 286 | 285 | 
| 287 static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { |  | 
| 288     return lazy->isValid() ? lazy->get() : lazy->set(orig); |  | 
| 289 } |  | 
| 290 |  | 
| 291 /** |  | 
| 292  *  If the paint has an imagefilter, but it can be simplified to just a colorfil
      ter, return that |  | 
| 293  *  colorfilter, else return NULL. |  | 
| 294  */ |  | 
| 295 static SkColorFilter* image_to_color_filter(const SkPaint& paint) { |  | 
| 296     SkImageFilter* imgf = paint.getImageFilter(); |  | 
| 297     if (!imgf) { |  | 
| 298         return NULL; |  | 
| 299     } |  | 
| 300 |  | 
| 301     SkColorFilter* imgCF; |  | 
| 302     if (!imgf->asAColorFilter(&imgCF)) { |  | 
| 303         return NULL; |  | 
| 304     } |  | 
| 305 |  | 
| 306     SkColorFilter* paintCF = paint.getColorFilter(); |  | 
| 307     if (NULL == paintCF) { |  | 
| 308         // there is no existing paint colorfilter, so we can just return the ima
      gefilter's |  | 
| 309         return imgCF; |  | 
| 310     } |  | 
| 311 |  | 
| 312     // The paint has both a colorfilter and an imagefilter. |  | 
| 313     SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); |  | 
| 314     return SkColorFilter::CreateComposeFilter(imgCF, paintCF); |  | 
| 315 } |  | 
| 316 |  | 
| 317 class AutoDrawLooper { | 286 class AutoDrawLooper { | 
| 318 public: | 287 public: | 
| 319     AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
       paint, | 288     AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
       paint, | 
| 320                    bool skipLayerForImageFilter = false, | 289                    bool skipLayerForImageFilter = false, | 
| 321                    const SkRect* bounds = NULL) : fOrigPaint(paint) { | 290                    const SkRect* bounds = NULL) : fOrigPaint(paint) { | 
| 322         fCanvas = canvas; | 291         fCanvas = canvas; | 
| 323         fFilter = canvas->getDrawFilter(); | 292         fFilter = canvas->getDrawFilter(); | 
| 324         fPaint = &fOrigPaint; | 293         fPaint = &fOrigPaint; | 
| 325         fSaveCount = canvas->getSaveCount(); | 294         fSaveCount = canvas->getSaveCount(); | 
| 326         fDoClearImageFilter = false; | 295         fDoClearImageFilter = false; | 
| 327         fDone = false; | 296         fDone = false; | 
| 328 | 297 | 
| 329         SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); | 298         if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { | 
| 330         if (simplifiedCF) { |  | 
| 331             SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); |  | 
| 332             paint->setColorFilter(simplifiedCF)->unref(); |  | 
| 333             paint->setImageFilter(NULL); |  | 
| 334             fPaint = paint; |  | 
| 335         } |  | 
| 336 |  | 
| 337         if (!skipLayerForImageFilter && fPaint->getImageFilter()) { |  | 
| 338             SkPaint tmp; | 299             SkPaint tmp; | 
| 339             tmp.setImageFilter(fPaint->getImageFilter()); | 300             tmp.setImageFilter(fOrigPaint.getImageFilter()); | 
| 340             (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa
      yer_SaveFlag, | 301             (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa
      yer_SaveFlag, | 
| 341                                             true, SkCanvas::kFullLayer_SaveLayer
      Strategy); | 302                                             true, SkCanvas::kFullLayer_SaveLayer
      Strategy); | 
| 342             // we'll clear the imageFilter for the actual draws in next(), so | 303             // we'll clear the imageFilter for the actual draws in next(), so | 
| 343             // it will only be applied during the restore(). | 304             // it will only be applied during the restore(). | 
| 344             fDoClearImageFilter = true; | 305             fDoClearImageFilter = true; | 
| 345         } | 306         } | 
| 346 | 307 | 
| 347         if (SkDrawLooper* looper = paint.getLooper()) { | 308         if (SkDrawLooper* looper = paint.getLooper()) { | 
| 348             void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
      t>( | 309             void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
      t>( | 
| 349                     looper->contextSize()); | 310                     looper->contextSize()); | 
| 350             fLooperContext = looper->createContext(canvas, buffer); | 311             fLooperContext = looper->createContext(canvas, buffer); | 
| 351             fIsSimple = false; | 312             fIsSimple = false; | 
| 352         } else { | 313         } else { | 
| 353             fLooperContext = NULL; | 314             fLooperContext = NULL; | 
| 354             // can we be marked as simple? | 315             // can we be marked as simple? | 
| 355             fIsSimple = !fFilter && !fDoClearImageFilter; | 316             fIsSimple = !fFilter && !fDoClearImageFilter; | 
| 356         } | 317         } | 
| 357 | 318 | 
| 358         uint32_t oldFlags = paint.getFlags(); | 319         uint32_t oldFlags = paint.getFlags(); | 
| 359         fNewPaintFlags = filter_paint_flags(props, oldFlags); | 320         fNewPaintFlags = filter_paint_flags(props, oldFlags); | 
| 360         if (fIsSimple && (fNewPaintFlags != oldFlags)) { | 321         if (fIsSimple && (fNewPaintFlags != oldFlags)) { | 
| 361             SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); | 322             SkPaint* paint = fLazyPaint.set(fOrigPaint); | 
| 362             paint->setFlags(fNewPaintFlags); | 323             paint->setFlags(fNewPaintFlags); | 
| 363             fPaint = paint; | 324             fPaint = paint; | 
| 364             // if we're not simple, doNext() will take care of calling setFlags(
      ) | 325             // if we're not simple, doNext() will take care of calling setFlags(
      ) | 
| 365         } | 326         } | 
| 366     } | 327     } | 
| 367 | 328 | 
| 368     ~AutoDrawLooper() { | 329     ~AutoDrawLooper() { | 
| 369         if (fDoClearImageFilter) { | 330         if (fDoClearImageFilter) { | 
| 370             fCanvas->internalRestore(); | 331             fCanvas->internalRestore(); | 
| 371         } | 332         } | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 382             return false; | 343             return false; | 
| 383         } else if (fIsSimple) { | 344         } else if (fIsSimple) { | 
| 384             fDone = true; | 345             fDone = true; | 
| 385             return !fPaint->nothingToDraw(); | 346             return !fPaint->nothingToDraw(); | 
| 386         } else { | 347         } else { | 
| 387             return this->doNext(drawType); | 348             return this->doNext(drawType); | 
| 388         } | 349         } | 
| 389     } | 350     } | 
| 390 | 351 | 
| 391 private: | 352 private: | 
| 392     SkLazyPaint     fLazyPaintInit, fLazyPaintPerNext; | 353     SkLazyPaint     fLazyPaint; | 
| 393     SkCanvas*       fCanvas; | 354     SkCanvas*       fCanvas; | 
| 394     const SkPaint&  fOrigPaint; | 355     const SkPaint&  fOrigPaint; | 
| 395     SkDrawFilter*   fFilter; | 356     SkDrawFilter*   fFilter; | 
| 396     const SkPaint*  fPaint; | 357     const SkPaint*  fPaint; | 
| 397     int             fSaveCount; | 358     int             fSaveCount; | 
| 398     uint32_t        fNewPaintFlags; | 359     uint32_t        fNewPaintFlags; | 
| 399     bool            fDoClearImageFilter; | 360     bool            fDoClearImageFilter; | 
| 400     bool            fDone; | 361     bool            fDone; | 
| 401     bool            fIsSimple; | 362     bool            fIsSimple; | 
| 402     SkDrawLooper::Context* fLooperContext; | 363     SkDrawLooper::Context* fLooperContext; | 
| 403     SkSmallAllocator<1, 32> fLooperContextAllocator; | 364     SkSmallAllocator<1, 32> fLooperContextAllocator; | 
| 404 | 365 | 
| 405     bool doNext(SkDrawFilter::Type drawType); | 366     bool doNext(SkDrawFilter::Type drawType); | 
| 406 }; | 367 }; | 
| 407 | 368 | 
| 408 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { | 369 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { | 
| 409     fPaint = NULL; | 370     fPaint = NULL; | 
| 410     SkASSERT(!fIsSimple); | 371     SkASSERT(!fIsSimple); | 
| 411     SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); | 372     SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); | 
| 412 | 373 | 
| 413     SkPaint* paint = fLazyPaintPerNext.set(fLazyPaintInit.isValid() ? | 374     SkPaint* paint = fLazyPaint.set(fOrigPaint); | 
| 414                                            *fLazyPaintInit.get() : fOrigPaint); |  | 
| 415     paint->setFlags(fNewPaintFlags); | 375     paint->setFlags(fNewPaintFlags); | 
| 416 | 376 | 
| 417     if (fDoClearImageFilter) { | 377     if (fDoClearImageFilter) { | 
| 418         paint->setImageFilter(NULL); | 378         paint->setImageFilter(NULL); | 
| 419     } | 379     } | 
| 420 | 380 | 
| 421     if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { | 381     if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { | 
| 422         fDone = true; | 382         fDone = true; | 
| 423         return false; | 383         return false; | 
| 424     } | 384     } | 
| (...skipping 2138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2563     } | 2523     } | 
| 2564 | 2524 | 
| 2565     if (matrix) { | 2525     if (matrix) { | 
| 2566         canvas->concat(*matrix); | 2526         canvas->concat(*matrix); | 
| 2567     } | 2527     } | 
| 2568 } | 2528 } | 
| 2569 | 2529 | 
| 2570 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2530 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 
| 2571     fCanvas->restoreToCount(fSaveCount); | 2531     fCanvas->restoreToCount(fSaveCount); | 
| 2572 } | 2532 } | 
| OLD | NEW | 
|---|