michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include "SkTransparentShader.h" michael@0: #include "SkColorPriv.h" michael@0: #include "SkString.h" michael@0: michael@0: bool SkTransparentShader::setContext(const SkBitmap& device, michael@0: const SkPaint& paint, michael@0: const SkMatrix& matrix) { michael@0: fDevice = &device; michael@0: fAlpha = paint.getAlpha(); michael@0: michael@0: return this->INHERITED::setContext(device, paint, matrix); michael@0: } michael@0: michael@0: uint32_t SkTransparentShader::getFlags() { michael@0: uint32_t flags = this->INHERITED::getFlags(); michael@0: michael@0: switch (fDevice->colorType()) { michael@0: case kRGB_565_SkColorType: michael@0: flags |= kHasSpan16_Flag; michael@0: if (fAlpha == 255) michael@0: flags |= kOpaqueAlpha_Flag; michael@0: break; michael@0: case kPMColor_SkColorType: michael@0: if (fAlpha == 255 && fDevice->isOpaque()) michael@0: flags |= kOpaqueAlpha_Flag; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: return flags; michael@0: } michael@0: michael@0: void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { michael@0: unsigned scale = SkAlpha255To256(fAlpha); michael@0: michael@0: switch (fDevice->colorType()) { michael@0: case kPMColor_SkColorType: michael@0: if (scale == 256) { michael@0: SkPMColor* src = fDevice->getAddr32(x, y); michael@0: if (src != span) { michael@0: memcpy(span, src, count * sizeof(SkPMColor)); michael@0: } michael@0: } else { michael@0: const SkPMColor* src = fDevice->getAddr32(x, y); michael@0: for (int i = count - 1; i >= 0; --i) { michael@0: span[i] = SkAlphaMulQ(src[i], scale); michael@0: } michael@0: } michael@0: break; michael@0: case kRGB_565_SkColorType: { michael@0: const uint16_t* src = fDevice->getAddr16(x, y); michael@0: if (scale == 256) { michael@0: for (int i = count - 1; i >= 0; --i) { michael@0: span[i] = SkPixel16ToPixel32(src[i]); michael@0: } michael@0: } else { michael@0: unsigned alpha = fAlpha; michael@0: for (int i = count - 1; i >= 0; --i) { michael@0: uint16_t c = src[i]; michael@0: unsigned r = SkPacked16ToR32(c); michael@0: unsigned g = SkPacked16ToG32(c); michael@0: unsigned b = SkPacked16ToB32(c); michael@0: michael@0: span[i] = SkPackARGB32( alpha, michael@0: SkAlphaMul(r, scale), michael@0: SkAlphaMul(g, scale), michael@0: SkAlphaMul(b, scale)); michael@0: } michael@0: } michael@0: break; michael@0: } michael@0: case kAlpha_8_SkColorType: { michael@0: const uint8_t* src = fDevice->getAddr8(x, y); michael@0: if (scale == 256) { michael@0: for (int i = count - 1; i >= 0; --i) { michael@0: span[i] = SkPackARGB32(src[i], 0, 0, 0); michael@0: } michael@0: } else { michael@0: for (int i = count - 1; i >= 0; --i) { michael@0: span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); michael@0: } michael@0: } michael@0: break; michael@0: } michael@0: default: michael@0: SkDEBUGFAIL("colorType not supported as a destination device"); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) { michael@0: SkASSERT(fDevice->colorType() == kRGB_565_SkColorType); michael@0: michael@0: uint16_t* src = fDevice->getAddr16(x, y); michael@0: if (src != span) { michael@0: memcpy(span, src, count << 1); michael@0: } michael@0: } michael@0: michael@0: #ifndef SK_IGNORE_TO_STRING michael@0: void SkTransparentShader::toString(SkString* str) const { michael@0: str->append("SkTransparentShader: ("); michael@0: michael@0: this->INHERITED::toString(str); michael@0: michael@0: str->append(")"); michael@0: } michael@0: #endif