Index: src/core/SkCanvas.cpp |
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
index 68ced602f62da23dc3094de28326797c5502652b..2434fc360e726e84ee0d118b8469d53da351d4a7 100644 |
--- a/src/core/SkCanvas.cpp |
+++ b/src/core/SkCanvas.cpp |
@@ -308,17 +308,29 @@ public: |
fFilter = canvas->getDrawFilter(); |
fPaint = &fOrigPaint; |
fSaveCount = canvas->getSaveCount(); |
- fDoClearImageFilter = false; |
+ fTempLayerForImageFilter = false; |
fDone = false; |
if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { |
+ /** |
+ * We implement ImageFilters for a given draw by creating a layer, then applying the |
+ * imagefilter to the pixels of that layer (its backing surface/image), and then |
+ * we call restore() to apply that layer to the main canvas. |
+ * |
+ * To generate the src pixels for the filter, we remove the imagefilter and the |
+ * xfermode from the paint that we (AutoDrawLooper) return (fPaint). The imagefilter |
+ * is applied right before the restore, and the xfermode is applied during the restore. |
Stephen White
2015/04/20 14:36:46
Nit: this might be slightly misleading: the imagef
reed1
2015/04/20 14:49:19
Done.
|
+ * |
+ * We strip the imagefilter/xfermode inside doNext(). |
+ */ |
SkPaint tmp; |
+ // store the imagefilter/xfermode on the layer's paint, so they can be applied in |
+ // restore. |
tmp.setImageFilter(fOrigPaint.getImageFilter()); |
+ tmp.setXfermode(fOrigPaint.getXfermode()); |
(void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, |
SkCanvas::kFullLayer_SaveLayerStrategy); |
- // we'll clear the imageFilter for the actual draws in next(), so |
- // it will only be applied during the restore(). |
- fDoClearImageFilter = true; |
+ fTempLayerForImageFilter = true; |
Stephen White
2015/04/20 14:36:46
This name is much clearer to me; thanks for that!
|
} |
if (SkDrawLooper* looper = paint.getLooper()) { |
@@ -329,7 +341,7 @@ public: |
} else { |
fLooperContext = NULL; |
// can we be marked as simple? |
- fIsSimple = !fFilter && !fDoClearImageFilter; |
+ fIsSimple = !fFilter && !fTempLayerForImageFilter; |
} |
uint32_t oldFlags = paint.getFlags(); |
@@ -343,7 +355,7 @@ public: |
} |
~AutoDrawLooper() { |
- if (fDoClearImageFilter) { |
+ if (fTempLayerForImageFilter) { |
fCanvas->internalRestore(); |
} |
SkASSERT(fCanvas->getSaveCount() == fSaveCount); |
@@ -373,7 +385,7 @@ private: |
const SkPaint* fPaint; |
int fSaveCount; |
uint32_t fNewPaintFlags; |
- bool fDoClearImageFilter; |
+ bool fTempLayerForImageFilter; |
bool fDone; |
bool fIsSimple; |
SkDrawLooper::Context* fLooperContext; |
@@ -385,13 +397,14 @@ private: |
bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
fPaint = NULL; |
SkASSERT(!fIsSimple); |
- SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); |
+ SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); |
SkPaint* paint = fLazyPaint.set(fOrigPaint); |
paint->setFlags(fNewPaintFlags); |
- if (fDoClearImageFilter) { |
+ if (fTempLayerForImageFilter) { |
paint->setImageFilter(NULL); |
+ paint->setXfermode(NULL); |
} |
if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { |