OLD | NEW |
| (Empty) |
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 | |
14 SkShader::Context* SkTransparentShader::onCreateContext(const ContextRec& rec, | |
15 void* storage) const { | |
16 return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, rec))
; | |
17 } | |
18 | |
19 size_t SkTransparentShader::contextSize() const { | |
20 return sizeof(TransparentShaderContext); | |
21 } | |
22 | |
23 SkTransparentShader::TransparentShaderContext::TransparentShaderContext( | |
24 const SkTransparentShader& shader, const ContextRec& rec) | |
25 : INHERITED(shader, rec) | |
26 , fDevice(rec.fDevice) {} | |
27 | |
28 SkTransparentShader::TransparentShaderContext::~TransparentShaderContext() {} | |
29 | |
30 uint32_t SkTransparentShader::TransparentShaderContext::getFlags() const { | |
31 uint32_t flags = this->INHERITED::getFlags(); | |
32 | |
33 switch (fDevice->colorType()) { | |
34 case kRGB_565_SkColorType: | |
35 flags |= kHasSpan16_Flag; | |
36 if (this->getPaintAlpha() == 255) | |
37 flags |= kOpaqueAlpha_Flag; | |
38 break; | |
39 case kN32_SkColorType: | |
40 if (this->getPaintAlpha() == 255 && fDevice->isOpaque()) | |
41 flags |= kOpaqueAlpha_Flag; | |
42 break; | |
43 default: | |
44 break; | |
45 } | |
46 return flags; | |
47 } | |
48 | |
49 void SkTransparentShader::TransparentShaderContext::shadeSpan(int x, int y, SkPM
Color span[], | |
50 int count) { | |
51 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); | |
52 | |
53 switch (fDevice->colorType()) { | |
54 case kN32_SkColorType: | |
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 kRGB_565_SkColorType: { | |
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 = this->getPaintAlpha(); | |
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 kAlpha_8_SkColorType: { | |
90 const uint8_t* src = fDevice->getAddr8(x, y); | |
91 if (scale == 256) { | |
92 for (int i = count - 1; i >= 0; --i) { | |
93 span[i] = SkPackARGB32(src[i], 0, 0, 0); | |
94 } | |
95 } else { | |
96 for (int i = count - 1; i >= 0; --i) { | |
97 span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); | |
98 } | |
99 } | |
100 break; | |
101 } | |
102 default: | |
103 SkDEBUGFAIL("colorType not supported as a destination device"); | |
104 break; | |
105 } | |
106 } | |
107 | |
108 void SkTransparentShader::TransparentShaderContext::shadeSpan16(int x, int y, ui
nt16_t span[], | |
109 int count) { | |
110 SkASSERT(fDevice->colorType() == kRGB_565_SkColorType); | |
111 | |
112 uint16_t* src = fDevice->getAddr16(x, y); | |
113 if (src != span) { | |
114 memcpy(span, src, count << 1); | |
115 } | |
116 } | |
117 | |
118 SkFlattenable* SkTransparentShader::CreateProc(SkReadBuffer& buffer) { | |
119 return SkNEW(SkTransparentShader); | |
120 } | |
121 | |
122 #ifndef SK_IGNORE_TO_STRING | |
123 void SkTransparentShader::toString(SkString* str) const { | |
124 str->append("SkTransparentShader: ("); | |
125 | |
126 this->INHERITED::toString(str); | |
127 | |
128 str->append(")"); | |
129 } | |
130 #endif | |
OLD | NEW |