aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkColorFilter.h11
-rw-r--r--src/core/SkBlitter.cpp67
-rw-r--r--src/core/SkColorFilter.cpp9
3 files changed, 43 insertions, 44 deletions
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 581806bfe5..aee60196f6 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -65,6 +65,15 @@ public:
*/
virtual uint32_t getFlags() { return 0; }
+ /**
+ * Apply this colorfilter to the specified SkColor. This routine handles
+ * converting to SkPMColor, calling the filter, and then converting back
+ * to SkColor. This method is not virtual, but will call filterSpan()
+ * which is virtual.
+ */
+ SkColor filterColor(SkColor);
+
+
/** Create a colorfilter that uses the specified color and mode.
If the Mode is DST, this function will return NULL (since that
mode will have no effect on the result).
@@ -90,7 +99,7 @@ public:
are ignored.
*/
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
-
+
protected:
SkColorFilter() {}
SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index cd3cb1bd10..08b21dcfb0 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -666,36 +666,6 @@ private:
#include "SkCoreBlitters.h"
-class SkAutoRestoreShaderXfer {
-public:
- SkAutoRestoreShaderXfer(const SkPaint& p) : fPaint((SkPaint*)&p) {
- fShader = fPaint->getShader();
- SkSafeRef(fShader);
- fXfer = fPaint->getXfermode();
- SkSafeRef(fXfer);
- }
-
- ~SkAutoRestoreShaderXfer() {
- fPaint->setShader(fShader);
- SkSafeUnref(fShader);
- fPaint->setXfermode(fXfer);
- SkSafeUnref(fXfer);
- }
-
- SkShader* setShader(SkShader* shader) {
- return fPaint->setShader(shader);
- }
-
- SkXfermode* setXfermode(SkXfermode* mode) {
- return fPaint->setXfermode(mode);
- }
-
-private:
- SkPaint* fPaint;
- SkShader* fShader;
- SkXfermode* fXfer;
-};
-
class SkAutoCallProc {
public:
typedef void (*Proc)(void*);
@@ -790,7 +760,7 @@ static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
SkBlitter* SkBlitter::Choose(const SkBitmap& device,
const SkMatrix& matrix,
- const SkPaint& paint,
+ const SkPaint& origPaint,
void* storage, size_t storageSize) {
SkASSERT(storageSize == 0 || storage != NULL);
@@ -803,23 +773,24 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
return blitter;
}
- SkAutoRestoreShaderXfer restorePaint(paint);
+ SkPaint paint(origPaint);
SkShader* shader = paint.getShader();
+ SkColorFilter* cf = paint.getColorFilter();
+ SkXfermode* mode = paint.getXfermode();
Sk3DShader* shader3D = NULL;
if (paint.getMaskFilter() != NULL &&
paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
shader3D = SkNEW_ARGS(Sk3DShader, (shader));
- restorePaint.setShader(shader3D)->unref();
+ paint.setShader(shader3D)->unref();
shader = shader3D;
}
- SkXfermode* mode = paint.getXfermode();
if (NULL != mode) {
switch (interpret_xfermode(paint, mode, device.config())) {
case kSrcOver_XferInterp:
mode = NULL;
- restorePaint.setXfermode(NULL);
+ paint.setXfermode(NULL);
break;
case kSkipDrawing_XferInterp:
SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
@@ -829,16 +800,28 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
}
}
- if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL)) {
- // xfermodes (and filters) require shaders for our current blitters
- shader = SkNEW(SkColorShader);
- restorePaint.setShader(shader)->unref();
+ if (NULL == shader) {
+#ifdef SK_IGNORE_CF_OPTIMIZATION
+ if (mode || cf) {
+#else
+ if (mode) {
+#endif
+ // xfermodes (and filters) require shaders for our current blitters
+ shader = SkNEW(SkColorShader);
+ paint.setShader(shader)->unref();
+ } else if (cf) {
+ // if no shader && no xfermode, we just apply the colorfilter to
+ // our color and move on.
+ paint.setColor(cf->filterColor(paint.getColor()));
+ paint.setColorFilter(NULL);
+ cf = NULL;
+ }
}
- if (paint.getColorFilter() != NULL) {
+ if (cf) {
SkASSERT(shader);
- shader = SkNEW_ARGS(SkFilterShader, (shader, paint.getColorFilter()));
- restorePaint.setShader(shader)->unref();
+ shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
+ paint.setShader(shader)->unref();
// blitters should ignore the presence/absence of a filter, since
// if there is one, the shader will take care of it.
}
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 6bc6d08d05..0508be78e6 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -17,6 +17,7 @@
#include "SkColorFilter.h"
#include "SkShader.h"
+#include "SkUnPreMultiply.h"
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) {
return false;
@@ -31,7 +32,13 @@ void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[])
memcpy(d, s, count * sizeof(uint16_t));
}
-//////////////////////////////////////////////////////////////////////////////
+SkColor SkColorFilter::filterColor(SkColor c) {
+ SkPMColor dst, src = SkPreMultiplyColor(c);
+ this->filterSpan(&src, 1, &dst);
+ return SkUnPreMultiply::PMColorToColor(dst);
+}
+
+///////////////////////////////////////////////////////////////////////////////
SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter)
{