diff options
Diffstat (limited to 'skia/effects/SkTransparentShader.cpp')
-rw-r--r-- | skia/effects/SkTransparentShader.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/skia/effects/SkTransparentShader.cpp b/skia/effects/SkTransparentShader.cpp new file mode 100644 index 0000000..0c08543 --- /dev/null +++ b/skia/effects/SkTransparentShader.cpp @@ -0,0 +1,144 @@ +/* libs/graphics/effects/SkTransparentShader.cpp +** +** Copyright 2006, Google Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include "SkTransparentShader.h" +#include "SkColorPriv.h" + +bool SkTransparentShader::setContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix) +{ + fDevice = &device; + fAlpha = paint.getAlpha(); + + return this->INHERITED::setContext(device, paint, matrix); +} + +uint32_t SkTransparentShader::getFlags() +{ + uint32_t flags = this->INHERITED::getFlags(); + + switch (fDevice->getConfig()) { + case SkBitmap::kRGB_565_Config: + flags |= kHasSpan16_Flag; + if (fAlpha == 255) + flags |= kOpaqueAlpha_Flag; + break; + case SkBitmap::kARGB_8888_Config: + case SkBitmap::kARGB_4444_Config: + if (fAlpha == 255 && fDevice->isOpaque()) + flags |= kOpaqueAlpha_Flag; + break; + default: + break; + } + return flags; +} + +void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) +{ + unsigned scale = SkAlpha255To256(fAlpha); + + switch (fDevice->getConfig()) { + case SkBitmap::kARGB_8888_Config: + if (scale == 256) + memcpy(span, fDevice->getAddr32(x, y), count * sizeof(SkPMColor)); + else + { + const SkPMColor* src = fDevice->getAddr32(x, y); + for (int i = count - 1; i >= 0; --i) + span[i] = SkAlphaMulQ(src[i], scale); + } + break; + case SkBitmap::kRGB_565_Config: + { + const uint16_t* src = fDevice->getAddr16(x, y); + if (scale == 256) + { + for (int i = count - 1; i >= 0; --i) + span[i] = SkPixel16ToPixel32(src[i]); + } + else + { + unsigned alpha = fAlpha; + for (int i = count - 1; i >= 0; --i) + { + uint16_t c = src[i]; + unsigned r = SkPacked16ToR32(c); + unsigned g = SkPacked16ToG32(c); + unsigned b = SkPacked16ToB32(c); + + span[i] = SkPackARGB32( alpha, + SkAlphaMul(r, scale), + SkAlphaMul(g, scale), + SkAlphaMul(b, scale)); + } + } + } + break; + case SkBitmap::kARGB_4444_Config: + { + const uint16_t* src = fDevice->getAddr16(x, y); + if (scale == 256) + { + for (int i = count - 1; i >= 0; --i) + span[i] = SkPixel4444ToPixel32(src[i]); + } + else + { + unsigned scale16 = scale >> 4; + for (int i = count - 1; i >= 0; --i) + { + uint32_t c = SkExpand_4444(src[i]) * scale16; + span[i] = SkCompact_8888(c); + } + } + } + break; + case SkBitmap::kIndex8_Config: + SkASSERT(!"index8 not supported as a destination device"); + break; + case SkBitmap::kA8_Config: + { + const uint8_t* src = fDevice->getAddr8(x, y); + if (scale == 256) + { + for (int i = count - 1; i >= 0; --i) + span[i] = SkPackARGB32(src[i], 0, 0, 0); + } + else + { + for (int i = count - 1; i >= 0; --i) + span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); + } + } + break; + case SkBitmap::kA1_Config: + SkASSERT(!"kA1_Config umimplemented at this time"); + break; + default: // to avoid warnings + break; + } +} + +void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) +{ + SkASSERT(fDevice->getConfig() == SkBitmap::kRGB_565_Config); + + memcpy(span, fDevice->getAddr16(x, y), count << 1); +} + |