blob: 6b79839fe6b5d6253428dd551715da7393e71765 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* 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
21bool 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
31uint32_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
52void 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
138void 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