diff options
author | 2009-04-01 18:31:44 +0000 | |
---|---|---|
committer | 2009-04-01 18:31:44 +0000 | |
commit | d252db03d9650013b545ef9781fe993c07f8f314 (patch) | |
tree | 85afe2a17d58115d5e62225487e27308c7ad5f82 /src/core/SkBlitter.cpp | |
parent | 6c924ad46c89955e78e071c792ef00df9910b42f (diff) |
API change: SkPath computeBounds -> getBounds
git-svn-id: http://skia.googlecode.com/svn/trunk@140 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBlitter.cpp')
-rw-r--r-- | src/core/SkBlitter.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 920842937c..25303ac6b8 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -784,6 +784,64 @@ static void delete_blitter(void* blitter) SkDELETE((SkBlitter*)blitter); } +static bool just_solid_color(const SkPaint& paint) { + if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { + SkShader* shader = paint.getShader(); + if (NULL == shader || + (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { + return true; + } + } + return false; +} + +/** By analyzing the paint (with an xfermode), we may decide we can take + special action. This enum lists our possible actions + */ +enum XferInterp { + kNormal_XferInterp, // no special interpretation, draw normally + kSrcOver_XferInterp, // draw as if in srcover mode + kSkipDrawing_XferInterp // draw nothing +}; + +static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, + SkBitmap::Config deviceConfig) { + SkPorterDuff::Mode mode; + + if (SkPorterDuff::IsMode(xfer, &mode)) { + switch (mode) { + case SkPorterDuff::kSrc_Mode: + if (just_solid_color(paint)) { + return kSrcOver_XferInterp; + } + break; + case SkPorterDuff::kDst_Mode: + return kSkipDrawing_XferInterp; + case SkPorterDuff::kSrcOver_Mode: + return kSrcOver_XferInterp; + case SkPorterDuff::kDstOver_Mode: + if (SkBitmap::kRGB_565_Config == deviceConfig) { + return kSkipDrawing_XferInterp; + } + break; + case SkPorterDuff::kSrcIn_Mode: + if (SkBitmap::kRGB_565_Config == deviceConfig && + just_solid_color(paint)) { + return kSrcOver_XferInterp; + } + break; + case SkPorterDuff::kDstIn_Mode: + if (just_solid_color(paint)) { + return kSkipDrawing_XferInterp; + } + break; + default: + break; + } + } + return kNormal_XferInterp; +} + SkBlitter* SkBlitter::Choose(const SkBitmap& device, const SkMatrix& matrix, const SkPaint& paint, @@ -813,6 +871,19 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, } SkXfermode* mode = paint.getXfermode(); + if (NULL != mode) { + switch (interpret_xfermode(paint, mode, device.config())) { + case kSrcOver_XferInterp: + mode = NULL; + break; + case kSkipDrawing_XferInterp: + SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + return blitter; + default: + break; + } + } + if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL)) { // xfermodes require shaders for our current set of blitters |