• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/graphics/effects/SkTransparentShader.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include "SkTransparentShader.h"
19 #include "SkColorPriv.h"
20 
setContext(const SkBitmap & device,const SkPaint & paint,const SkMatrix & matrix)21 bool SkTransparentShader::setContext(const SkBitmap& device,
22                                      const SkPaint& paint,
23                                      const SkMatrix& matrix) {
24     fDevice = &device;
25     fAlpha = paint.getAlpha();
26 
27     return this->INHERITED::setContext(device, paint, matrix);
28 }
29 
getFlags()30 uint32_t SkTransparentShader::getFlags() {
31     uint32_t flags = this->INHERITED::getFlags();
32 
33     switch (fDevice->getConfig()) {
34         case SkBitmap::kRGB_565_Config:
35             flags |= kHasSpan16_Flag;
36             if (fAlpha == 255)
37                 flags |= kOpaqueAlpha_Flag;
38             break;
39         case SkBitmap::kARGB_8888_Config:
40         case SkBitmap::kARGB_4444_Config:
41             if (fAlpha == 255 && fDevice->isOpaque())
42                 flags |= kOpaqueAlpha_Flag;
43             break;
44         default:
45             break;
46     }
47     return flags;
48 }
49 
shadeSpan(int x,int y,SkPMColor span[],int count)50 void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
51     unsigned scale = SkAlpha255To256(fAlpha);
52 
53     switch (fDevice->getConfig()) {
54         case SkBitmap::kARGB_8888_Config:
55             if (scale == 256) {
56                 SkPMColor* src = fDevice->getAddr32(x, y);
57                 if (src != span) {
58                     memcpy(span, src, count * sizeof(SkPMColor));
59                 }
60             } else {
61                 const SkPMColor* src = fDevice->getAddr32(x, y);
62                 for (int i = count - 1; i >= 0; --i) {
63                     span[i] = SkAlphaMulQ(src[i], scale);
64                 }
65             }
66             break;
67         case SkBitmap::kRGB_565_Config: {
68             const uint16_t* src = fDevice->getAddr16(x, y);
69             if (scale == 256) {
70                 for (int i = count - 1; i >= 0; --i) {
71                     span[i] = SkPixel16ToPixel32(src[i]);
72                 }
73             } else {
74                 unsigned alpha = fAlpha;
75                 for (int i = count - 1; i >= 0; --i) {
76                     uint16_t c = src[i];
77                     unsigned r = SkPacked16ToR32(c);
78                     unsigned g = SkPacked16ToG32(c);
79                     unsigned b = SkPacked16ToB32(c);
80 
81                     span[i] = SkPackARGB32( alpha,
82                                             SkAlphaMul(r, scale),
83                                             SkAlphaMul(g, scale),
84                                             SkAlphaMul(b, scale));
85                 }
86             }
87             break;
88         }
89         case SkBitmap::kARGB_4444_Config: {
90             const uint16_t* src = fDevice->getAddr16(x, y);
91             if (scale == 256) {
92                 for (int i = count - 1; i >= 0; --i) {
93                     span[i] = SkPixel4444ToPixel32(src[i]);
94                 }
95             } else {
96                 unsigned scale16 = scale >> 4;
97                 for (int i = count - 1; i >= 0; --i) {
98                     uint32_t c = SkExpand_4444(src[i]) * scale16;
99                     span[i] = SkCompact_8888(c);
100                 }
101             }
102             break;
103         }
104         case SkBitmap::kIndex8_Config:
105             SkASSERT(!"index8 not supported as a destination device");
106             break;
107         case SkBitmap::kA8_Config: {
108             const uint8_t* src = fDevice->getAddr8(x, y);
109             if (scale == 256) {
110                 for (int i = count - 1; i >= 0; --i) {
111                     span[i] = SkPackARGB32(src[i], 0, 0, 0);
112                 }
113             } else {
114                 for (int i = count - 1; i >= 0; --i) {
115                     span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0);
116                 }
117             }
118             break;
119         }
120         case SkBitmap::kA1_Config:
121             SkASSERT(!"kA1_Config umimplemented at this time");
122             break;
123         default:    // to avoid warnings
124             break;
125     }
126 }
127 
shadeSpan16(int x,int y,uint16_t span[],int count)128 void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
129     SkASSERT(fDevice->getConfig() == SkBitmap::kRGB_565_Config);
130 
131     uint16_t* src = fDevice->getAddr16(x, y);
132     if (src != span) {
133         memcpy(span, src, count << 1);
134     }
135 }
136 
137