~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/skia/src/core/SkShader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* libs/graphics/sgl/SkShader.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 "SkShader.h"
 
19
#include "SkPaint.h"
 
20
 
 
21
SkShader::SkShader() : fLocalMatrix(NULL) {
 
22
    SkDEBUGCODE(fInSession = false;)
 
23
}
 
24
 
 
25
SkShader::SkShader(SkFlattenableReadBuffer& buffer)
 
26
        : INHERITED(buffer), fLocalMatrix(NULL) {
 
27
    if (buffer.readBool()) {
 
28
        SkMatrix matrix;
 
29
        buffer.read(&matrix, sizeof(matrix));
 
30
        setLocalMatrix(matrix);
 
31
    }
 
32
    SkDEBUGCODE(fInSession = false;)
 
33
}
 
34
 
 
35
SkShader::~SkShader() {
 
36
    SkASSERT(!fInSession);
 
37
    sk_free(fLocalMatrix);
 
38
}
 
39
 
 
40
void SkShader::beginSession() {
 
41
    SkASSERT(!fInSession);
 
42
    SkDEBUGCODE(fInSession = true;)
 
43
}
 
44
 
 
45
void SkShader::endSession() {
 
46
    SkASSERT(fInSession);
 
47
    SkDEBUGCODE(fInSession = false;)
 
48
}
 
49
 
 
50
void SkShader::flatten(SkFlattenableWriteBuffer& buffer) {
 
51
    this->INHERITED::flatten(buffer);
 
52
    buffer.writeBool(fLocalMatrix != NULL);
 
53
    if (fLocalMatrix) {
 
54
        buffer.writeMul4(fLocalMatrix, sizeof(SkMatrix));
 
55
    }
 
56
}
 
57
 
 
58
bool SkShader::getLocalMatrix(SkMatrix* localM) const {
 
59
    if (fLocalMatrix) {
 
60
        if (localM) {
 
61
            *localM = *fLocalMatrix;
 
62
        }
 
63
        return true;
 
64
    } else {
 
65
        if (localM) {
 
66
            localM->reset();
 
67
        }
 
68
        return false;
 
69
    }
 
70
}
 
71
 
 
72
void SkShader::setLocalMatrix(const SkMatrix& localM) {
 
73
    if (localM.isIdentity()) {
 
74
        this->resetLocalMatrix();
 
75
    } else {
 
76
        if (fLocalMatrix == NULL) {
 
77
            fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
 
78
        }
 
79
        *fLocalMatrix = localM;
 
80
    }
 
81
}
 
82
 
 
83
void SkShader::resetLocalMatrix() {
 
84
    if (fLocalMatrix) {
 
85
        sk_free(fLocalMatrix);
 
86
        fLocalMatrix = NULL;
 
87
    }
 
88
}
 
89
 
 
90
bool SkShader::setContext(const SkBitmap& device,
 
91
                          const SkPaint& paint,
 
92
                          const SkMatrix& matrix) {
 
93
    const SkMatrix* m = &matrix;
 
94
    SkMatrix        total;
 
95
 
 
96
    fDeviceConfig = SkToU8(device.getConfig());
 
97
    fPaintAlpha = paint.getAlpha();
 
98
    if (fLocalMatrix) {
 
99
        total.setConcat(matrix, *fLocalMatrix);
 
100
        m = &total;
 
101
    }
 
102
    if (m->invert(&fTotalInverse)) {
 
103
        fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
 
104
        return true;
 
105
    }
 
106
    return false;
 
107
}
 
108
 
 
109
#include "SkColorPriv.h"
 
110
 
 
111
void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {
 
112
    SkASSERT(span16);
 
113
    SkASSERT(count > 0);
 
114
    SkASSERT(this->canCallShadeSpan16());
 
115
 
 
116
    // basically, if we get here, the subclass screwed up
 
117
    SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented");
 
118
}
 
119
 
 
120
#define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
 
121
#define kTempColorCount     (kTempColorQuadCount << 2)  
 
122
 
 
123
#ifdef SK_CPU_BENDIAN
 
124
    #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
 
125
#else
 
126
    #define SkU32BitShiftToByteOffset(shift)    ((shift) >> 3)
 
127
#endif
 
128
 
 
129
void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
 
130
    SkASSERT(count > 0);
 
131
 
 
132
    SkPMColor   colors[kTempColorCount];
 
133
 
 
134
    while ((count -= kTempColorCount) >= 0) {
 
135
        this->shadeSpan(x, y, colors, kTempColorCount);
 
136
        x += kTempColorCount;
 
137
 
 
138
        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
 
139
        int quads = kTempColorQuadCount;
 
140
        do {
 
141
            U8CPU a0 = srcA[0];
 
142
            U8CPU a1 = srcA[4];
 
143
            U8CPU a2 = srcA[8];
 
144
            U8CPU a3 = srcA[12];
 
145
            srcA += 4*4;
 
146
            *alpha++ = SkToU8(a0);
 
147
            *alpha++ = SkToU8(a1);
 
148
            *alpha++ = SkToU8(a2);
 
149
            *alpha++ = SkToU8(a3);
 
150
        } while (--quads != 0);
 
151
    }
 
152
    SkASSERT(count < 0);
 
153
    SkASSERT(count + kTempColorCount >= 0);
 
154
    if (count += kTempColorCount) {
 
155
        this->shadeSpan(x, y, colors, count);
 
156
 
 
157
        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
 
158
        do {
 
159
            *alpha++ = *srcA;
 
160
            srcA += 4;
 
161
        } while (--count != 0);
 
162
    }
 
163
#if 0
 
164
    do {
 
165
        int n = count;
 
166
        if (n > kTempColorCount)
 
167
            n = kTempColorCount;
 
168
        SkASSERT(n > 0);
 
169
 
 
170
        this->shadeSpan(x, y, colors, n);
 
171
        x += n;
 
172
        count -= n;
 
173
 
 
174
        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
 
175
        do {
 
176
            *alpha++ = *srcA;
 
177
            srcA += 4;
 
178
        } while (--n != 0);
 
179
    } while (count > 0);
 
180
#endif
 
181
}
 
182
 
 
183
SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) {
 
184
    MatrixClass mc = kLinear_MatrixClass;
 
185
 
 
186
    if (mat.getType() & SkMatrix::kPerspective_Mask) {
 
187
        if (mat.fixedStepInX(0, NULL, NULL)) {
 
188
            mc = kFixedStepInX_MatrixClass;
 
189
        } else {
 
190
            mc = kPerspective_MatrixClass;
 
191
        }
 
192
    }
 
193
    return mc;
 
194
}
 
195
 
 
196
//////////////////////////////////////////////////////////////////////////////
 
197
 
 
198
bool SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) {
 
199
    return false;
 
200
}
 
201
 
 
202
SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
 
203
                                       TileMode tmx, TileMode tmy) {
 
204
    return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0);
 
205
}
 
206
 
 
207
//////////////////////////////////////////////////////////////////////////////
 
208
 
 
209
#include "SkColorShader.h"
 
210
#include "SkUtils.h"
 
211
 
 
212
SkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) {
 
213
    fInheritColor = b.readU8(); 
 
214
    if (fInheritColor) {
 
215
        return;
 
216
    }
 
217
    fColor = b.readU32();
 
218
}
 
219
 
 
220
void SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) {
 
221
    this->INHERITED::flatten(buffer);
 
222
    buffer.write8(fInheritColor);
 
223
    if (fInheritColor) {
 
224
        return;
 
225
    }
 
226
    buffer.write32(fColor);
 
227
}
 
228
 
 
229
uint32_t SkColorShader::getFlags() {
 
230
    return (SkGetPackedA32(fPMColor) == 255 ? kOpaqueAlpha_Flag : 0) |
 
231
            kHasSpan16_Flag;
 
232
}
 
233
 
 
234
uint8_t SkColorShader::getSpan16Alpha() const {
 
235
    return SkGetPackedA32(fPMColor);
 
236
}
 
237
 
 
238
bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
 
239
                               const SkMatrix& matrix) {
 
240
    if (!this->INHERITED::setContext(device, paint, matrix)) {
 
241
        return false;
 
242
    }
 
243
 
 
244
    SkColor c;
 
245
    unsigned a;
 
246
    
 
247
    if (fInheritColor) {
 
248
        c = paint.getColor();
 
249
        a = SkColorGetA(c);
 
250
    } else {
 
251
        c = fColor;
 
252
        a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
 
253
    }
 
254
 
 
255
    unsigned r = SkColorGetR(c);
 
256
    unsigned g = SkColorGetG(c);
 
257
    unsigned b = SkColorGetB(c);
 
258
 
 
259
    // we want this before we apply any alpha
 
260
    fColor16 = SkPack888ToRGB16(r, g, b);
 
261
 
 
262
    if (a != 255) {
 
263
        a = SkAlpha255To256(a);
 
264
        r = SkAlphaMul(r, a);
 
265
        g = SkAlphaMul(g, a);
 
266
        b = SkAlphaMul(b, a);
 
267
    }
 
268
    fPMColor = SkPackARGB32(a, r, g, b);
 
269
 
 
270
    return true;
 
271
}
 
272
 
 
273
void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
 
274
    sk_memset32(span, fPMColor, count);
 
275
}
 
276
 
 
277
void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
 
278
    sk_memset16(span, fColor16, count);
 
279
}
 
280
 
 
281
void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
 
282
    memset(alpha, SkGetPackedA32(fPMColor), count);
 
283
}
 
284