• 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 {
25     fDevice = &device;
26     fAlpha = paint.getAlpha();
27 
28     return this->INHERITED::setContext(device, paint, matrix);
29 }
30 
getFlags()31 uint32_t SkTransparentShader::getFlags()
32 {
33     uint32_t flags = this->INHERITED::getFlags();
34 
35     switch (fDevice->getConfig()) {
36     case SkBitmap::kRGB_565_Config:
37         flags |= kHasSpan16_Flag;
38         if (fAlpha == 255)
39             flags |= kOpaqueAlpha_Flag;
40         break;
41     case SkBitmap::kARGB_8888_Config:
42     case SkBitmap::kARGB_4444_Config:
43         if (fAlpha == 255 && fDevice->isOpaque())
44             flags |= kOpaqueAlpha_Flag;
45         break;
46     default:
47         break;
48     }
49     return flags;
50 }
51 
shadeSpan(int x,int y,SkPMColor span[],int count)52 void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count)
53 {
54     unsigned scale = SkAlpha255To256(fAlpha);
55 
56     switch (fDevice->getConfig()) {
57     case SkBitmap::kARGB_8888_Config:
58         if (scale == 256)
59             memcpy(span, fDevice->getAddr32(x, y), count * sizeof(SkPMColor));
60         else
61         {
62             const SkPMColor* src = fDevice->getAddr32(x, y);
63             for (int i = count - 1; i >= 0; --i)
64                 span[i] = SkAlphaMulQ(src[i], scale);
65         }
66         break;
67     case SkBitmap::kRGB_565_Config:
68         {
69             const uint16_t* src = fDevice->getAddr16(x, y);
70             if (scale == 256)
71             {
72                 for (int i = count - 1; i >= 0; --i)
73                     span[i] = SkPixel16ToPixel32(src[i]);
74             }
75             else
76             {
77                 unsigned alpha = fAlpha;
78                 for (int i = count - 1; i >= 0; --i)
79                 {
80                     uint16_t c = src[i];
81                     unsigned r = SkPacked16ToR32(c);
82                     unsigned g = SkPacked16ToG32(c);
83                     unsigned b = SkPacked16ToB32(c);
84 
85                     span[i] = SkPackARGB32( alpha,
86                                             SkAlphaMul(r, scale),
87                                             SkAlphaMul(g, scale),
88                                             SkAlphaMul(b, scale));
89                 }
90             }
91         }
92         break;
93     case SkBitmap::kARGB_4444_Config:
94         {
95             const uint16_t* src = fDevice->getAddr16(x, y);
96             if (scale == 256)
97             {
98                 for (int i = count - 1; i >= 0; --i)
99                     span[i] = SkPixel4444ToPixel32(src[i]);
100             }
101             else
102             {
103                 unsigned scale16 = scale >> 4;
104                 for (int i = count - 1; i >= 0; --i)
105                 {
106                     uint32_t c = SkExpand_4444(src[i]) * scale16;
107                     span[i] = SkCompact_8888(c);
108                 }
109             }
110         }
111             break;
112             case SkBitmap::kIndex8_Config:
113         SkASSERT(!"index8 not supported as a destination device");
114         break;
115     case SkBitmap::kA8_Config:
116         {
117             const uint8_t* src = fDevice->getAddr8(x, y);
118             if (scale == 256)
119             {
120                 for (int i = count - 1; i >= 0; --i)
121                     span[i] = SkPackARGB32(src[i], 0, 0, 0);
122             }
123             else
124             {
125                 for (int i = count - 1; i >= 0; --i)
126                     span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0);
127             }
128         }
129         break;
130     case SkBitmap::kA1_Config:
131         SkASSERT(!"kA1_Config umimplemented at this time");
132         break;
133     default:    // to avoid warnings
134         break;
135     }
136 }
137 
shadeSpan16(int x,int y,uint16_t span[],int count)138 void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count)
139 {
140     SkASSERT(fDevice->getConfig() == SkBitmap::kRGB_565_Config);
141 
142     memcpy(span, fDevice->getAddr16(x, y), count << 1);
143 }
144 
145