diff options
-rw-r--r-- | include/core/SkColorFilter.h | 11 | ||||
-rw-r--r-- | src/core/SkBlitter.cpp | 67 | ||||
-rw-r--r-- | src/core/SkColorFilter.cpp | 9 |
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) { |