diff options
Diffstat (limited to 'core/SkComposeShader.cpp')
-rw-r--r-- | core/SkComposeShader.cpp | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/core/SkComposeShader.cpp b/core/SkComposeShader.cpp index df8215c1..7a7dce66 100644 --- a/core/SkComposeShader.cpp +++ b/core/SkComposeShader.cpp @@ -73,55 +73,38 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const { buffer.writeFlattenable(fMode); } -/* We call validContext/createContext on our two worker shaders. - However, we always let them see opaque alpha, and if the paint - really is translucent, then we apply that after the fact. - - */ -bool SkComposeShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - if (!this->INHERITED::validContext(rec, totalInverse)) { - return false; +template <typename T> void safe_call_destructor(T* obj) { + if (obj) { + obj->~T(); } - - // we preconcat our localMatrix (if any) with the device matrix - // before calling our sub-shaders - - SkMatrix tmpM; - tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); - - ContextRec newRec(rec); - newRec.fMatrix = &tmpM; - - return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); } -SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* storage) const { - if (!this->validContext(rec)) { - return NULL; - } - - // TODO : must fix this to not "cheat" and modify fPaint - SkAutoAlphaRestore restore(const_cast<SkPaint*>(rec.fPaint), 0xFF); - +SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const { char* aStorage = (char*) storage + sizeof(ComposeShaderContext); char* bStorage = aStorage + fShaderA->contextSize(); // we preconcat our localMatrix (if any) with the device matrix // before calling our sub-shaders - SkMatrix tmpM; tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); + // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the + // result. ComposeShader itself will respect the alpha, and post-apply it after calling the + // sub-shaders. + SkPaint opaquePaint(*rec.fPaint); + opaquePaint.setAlpha(0xFF); + ContextRec newRec(rec); newRec.fMatrix = &tmpM; + newRec.fPaint = &opaquePaint; SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); - - // Both functions must succeed; otherwise validContext should have returned - // false. - SkASSERT(contextA); - SkASSERT(contextB); + if (!contextA || !contextB) { + safe_call_destructor(contextA); + safe_call_destructor(contextB); + return NULL; + } return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, contextA, contextB)); } @@ -148,6 +131,10 @@ void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode; unsigned scale = SkAlpha255To256(this->getPaintAlpha()); +#ifdef SK_BUILD_FOR_ANDROID + scale = 256; // ugh -- maintain old bug/behavior for now +#endif + SkPMColor tmp[TMP_COLOR_COUNT]; if (NULL == mode) { // implied SRC_OVER @@ -188,7 +175,7 @@ void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re shaderContextB->shadeSpan(x, y, tmp, n); mode->xfer32(result, tmp, n, NULL); - if (256 == scale) { + if (256 != scale) { for (int i = 0; i < n; i++) { result[i] = SkAlphaMulQ(result[i], scale); } |