SkTransparentShader.cpp revision 28fcae2ec77eb16a79e155f8d788b20457f1c951
1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "SkTransparentShader.h"
11#include "SkColorPriv.h"
12#include "SkString.h"
13
14bool SkTransparentShader::setContext(const SkBitmap& device,
15                                     const SkPaint& paint,
16                                     const SkMatrix& matrix) {
17    fDevice = &device;
18    fAlpha = paint.getAlpha();
19
20    return this->INHERITED::setContext(device, paint, matrix);
21}
22
23uint32_t SkTransparentShader::getFlags() {
24    uint32_t flags = this->INHERITED::getFlags();
25
26    switch (fDevice->colorType()) {
27        case kRGB_565_SkColorType:
28            flags |= kHasSpan16_Flag;
29            if (fAlpha == 255)
30                flags |= kOpaqueAlpha_Flag;
31            break;
32        case kN32_SkColorType:
33            if (fAlpha == 255 && fDevice->isOpaque())
34                flags |= kOpaqueAlpha_Flag;
35            break;
36        default:
37            break;
38    }
39    return flags;
40}
41
42void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
43    unsigned scale = SkAlpha255To256(fAlpha);
44
45    switch (fDevice->colorType()) {
46        case kN32_SkColorType:
47            if (scale == 256) {
48                SkPMColor* src = fDevice->getAddr32(x, y);
49                if (src != span) {
50                    memcpy(span, src, count * sizeof(SkPMColor));
51                }
52            } else {
53                const SkPMColor* src = fDevice->getAddr32(x, y);
54                for (int i = count - 1; i >= 0; --i) {
55                    span[i] = SkAlphaMulQ(src[i], scale);
56                }
57            }
58            break;
59        case kRGB_565_SkColorType: {
60            const uint16_t* src = fDevice->getAddr16(x, y);
61            if (scale == 256) {
62                for (int i = count - 1; i >= 0; --i) {
63                    span[i] = SkPixel16ToPixel32(src[i]);
64                }
65            } else {
66                unsigned alpha = fAlpha;
67                for (int i = count - 1; i >= 0; --i) {
68                    uint16_t c = src[i];
69                    unsigned r = SkPacked16ToR32(c);
70                    unsigned g = SkPacked16ToG32(c);
71                    unsigned b = SkPacked16ToB32(c);
72
73                    span[i] = SkPackARGB32( alpha,
74                                            SkAlphaMul(r, scale),
75                                            SkAlphaMul(g, scale),
76                                            SkAlphaMul(b, scale));
77                }
78            }
79            break;
80        }
81        case kAlpha_8_SkColorType: {
82            const uint8_t* src = fDevice->getAddr8(x, y);
83            if (scale == 256) {
84                for (int i = count - 1; i >= 0; --i) {
85                    span[i] = SkPackARGB32(src[i], 0, 0, 0);
86                }
87            } else {
88                for (int i = count - 1; i >= 0; --i) {
89                    span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0);
90                }
91            }
92            break;
93        }
94        default:
95            SkDEBUGFAIL("colorType not supported as a destination device");
96            break;
97    }
98}
99
100void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
101    SkASSERT(fDevice->colorType() == kRGB_565_SkColorType);
102
103    uint16_t* src = fDevice->getAddr16(x, y);
104    if (src != span) {
105        memcpy(span, src, count << 1);
106    }
107}
108
109#ifndef SK_IGNORE_TO_STRING
110void SkTransparentShader::toString(SkString* str) const {
111    str->append("SkTransparentShader: (");
112
113    this->INHERITED::toString(str);
114
115    str->append(")");
116}
117#endif
118