1
/* libs/graphics/effects/SkColorFilters.cpp
3
** Copyright 2006, The Android Open Source Project
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
9
** http://www.apache.org/licenses/LICENSE-2.0
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.
18
#include "SkColorFilter.h"
19
#include "SkColorPriv.h"
20
#include "SkPorterDuff.h"
23
//#define TRACE_CreatePorterDuffFilter
26
class Sk_XfermodeColorFilter : public SkColorFilter {
28
Sk_XfermodeColorFilter(SkColor color) : fColor(SkPreMultiplyColor(color)) {}
30
virtual void flatten(SkFlattenableWriteBuffer& buffer)
32
buffer.write32(fColor);
35
Sk_XfermodeColorFilter(SkFlattenableReadBuffer& buffer)
37
fColor = buffer.readU32();
43
class SkSrc_XfermodeColorFilter : public Sk_XfermodeColorFilter {
45
SkSrc_XfermodeColorFilter(SkColor color) : INHERITED(color) {}
47
virtual uint32_t getFlags()
49
if (SkGetPackedA32(fColor) == 0xFF)
50
return kAlphaUnchanged_Flag | kHasFilter16_Flag;
55
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
57
sk_memset32(result, fColor, count);
60
virtual void filterSpan16(const uint16_t shader[], int count, uint16_t result[])
62
SkASSERT(this->getFlags() & kHasFilter16_Flag);
64
sk_memset16(result, SkPixel32ToPixel16(fColor), count);
68
virtual Factory getFactory() { return CreateProc; }
70
SkSrc_XfermodeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
73
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
75
return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (buffer));
78
typedef Sk_XfermodeColorFilter INHERITED;
81
class SkSrcOver_XfermodeColorFilter : public Sk_XfermodeColorFilter {
83
SkSrcOver_XfermodeColorFilter(SkColor color) : INHERITED(color) {}
85
virtual uint32_t getFlags()
87
if (SkGetPackedA32(fColor) == 0xFF)
88
return kAlphaUnchanged_Flag | kHasFilter16_Flag;
93
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
95
SkPMColor src = fColor;
96
unsigned scale = SkAlpha255To256(255 - SkGetPackedA32(src));
98
for (int i = 0; i < count; i++)
99
result[i] = src + SkAlphaMulQ(shader[i], scale);
102
virtual void filterSpan16(const uint16_t shader[], int count, uint16_t result[])
104
SkASSERT(this->getFlags() & kHasFilter16_Flag);
106
sk_memset16(result, SkPixel32ToPixel16(fColor), count);
110
virtual Factory getFactory() { return CreateProc; }
112
SkSrcOver_XfermodeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
115
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
117
return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (buffer));
120
typedef Sk_XfermodeColorFilter INHERITED;
123
//////////////////////////////////////////////////////////////////////////////
125
class SkXfermodeColorFilter : public Sk_XfermodeColorFilter {
127
SkXfermodeColorFilter(SkColor color, SkXfermodeProc proc,
128
SkXfermodeProc16 proc16) : INHERITED(color)
134
virtual uint32_t getFlags()
136
return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0;
139
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
141
SkPMColor color = fColor;
142
SkXfermodeProc proc = fProc;
144
for (int i = 0; i < count; i++)
145
result[i] = proc(color, shader[i]);
148
virtual void filterSpan16(const uint16_t shader[], int count, uint16_t result[])
150
SkASSERT(this->getFlags() & kHasFilter16_Flag);
152
SkPMColor color = fColor;
153
SkXfermodeProc16 proc16 = fProc16;
155
for (int i = 0; i < count; i++)
156
result[i] = proc16(color, shader[i]);
160
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
161
this->INHERITED::flatten(buffer);
162
buffer.writeFunctionPtr((void*)fProc);
163
buffer.writeFunctionPtr((void*)fProc16);
166
virtual Factory getFactory() {
170
SkXfermodeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
171
fProc = (SkXfermodeProc) buffer.readFunctionPtr();
172
fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr();
175
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
176
return SkNEW_ARGS(SkXfermodeColorFilter, (buffer));
179
SkXfermodeProc fProc;
180
SkXfermodeProc16 fProc16;
182
typedef Sk_XfermodeColorFilter INHERITED;
185
SkColorFilter* SkColorFilter::CreatXfermodeProcFilter(SkColor color,
187
SkXfermodeProc16 proc16)
190
SkNEW_ARGS(SkXfermodeColorFilter, (color, proc, proc16)) :
194
///////////////////////////////////////////////////////////////////////////////
196
SkColorFilter* SkColorFilter::CreatePorterDuffFilter(SkColor color,
197
SkPorterDuff::Mode mode)
199
unsigned alpha = SkColorGetA(color);
201
// first collaps some modes if possible
203
if (SkPorterDuff::kClear_Mode == mode)
206
mode = SkPorterDuff::kSrc_Mode;
208
else if (SkPorterDuff::kSrcOver_Mode == mode)
212
mode = SkPorterDuff::kDst_Mode;
214
else if (255 == alpha)
216
mode = SkPorterDuff::kSrc_Mode;
218
// else just stay srcover
221
// weed out combinations that are noops, and just return null
222
if (SkPorterDuff::kDst_Mode == mode ||
223
(0 == alpha && (SkPorterDuff::kSrcOver_Mode == mode ||
224
SkPorterDuff::kDstOver_Mode == mode ||
225
SkPorterDuff::kDstOut_Mode == mode ||
226
SkPorterDuff::kSrcATop_Mode == mode ||
227
SkPorterDuff::kXor_Mode == mode ||
228
SkPorterDuff::kDarken_Mode == mode)) ||
229
(0xFF == alpha && SkPorterDuff::kDstIn_Mode == mode))
235
case SkPorterDuff::kSrc_Mode:
236
return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (color));
237
case SkPorterDuff::kSrcOver_Mode:
238
return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (color));
240
return SkColorFilter::CreatXfermodeProcFilter(color,
241
SkPorterDuff::GetXfermodeProc(mode),
242
SkPorterDuff::GetXfermodeProc16(mode, color));
246
/////////////////////////////////////////////////////////////////////////////////////////////////
248
static inline unsigned pin(unsigned value, unsigned max)
255
static inline unsigned SkUClampMax(unsigned value, unsigned max)
257
SkASSERT((int32_t)value >= 0);
258
SkASSERT((int32_t)max >= 0);
260
int diff = max - value;
261
// clear diff if diff is positive
267
class SkLightingColorFilter : public SkColorFilter {
269
SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {}
271
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
273
unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
274
unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
275
unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
277
unsigned addR = SkColorGetR(fAdd);
278
unsigned addG = SkColorGetG(fAdd);
279
unsigned addB = SkColorGetB(fAdd);
281
for (int i = 0; i < count; i++)
283
SkPMColor c = shader[i];
286
unsigned a = SkGetPackedA32(c);
287
unsigned scaleA = SkAlpha255To256(a);
288
unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a);
289
unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a);
290
unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a);
291
c = SkPackARGB32(a, r, g, b);
298
virtual void flatten(SkFlattenableWriteBuffer& buffer)
300
buffer.write32(fMul);
301
buffer.write32(fAdd);
304
virtual Factory getFactory()
309
SkLightingColorFilter(SkFlattenableReadBuffer& buffer)
311
fMul = buffer.readU32();
312
fAdd = buffer.readU32();
318
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
320
return SkNEW_ARGS(SkLightingColorFilter, (buffer));
324
class SkLightingColorFilter_JustAdd : public SkLightingColorFilter {
326
SkLightingColorFilter_JustAdd(SkColor mul, SkColor add)
327
: INHERITED(mul, add) {}
329
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
331
unsigned addR = SkColorGetR(fAdd);
332
unsigned addG = SkColorGetG(fAdd);
333
unsigned addB = SkColorGetB(fAdd);
335
for (int i = 0; i < count; i++)
337
SkPMColor c = shader[i];
340
unsigned a = SkGetPackedA32(c);
341
unsigned scaleA = SkAlpha255To256(a);
342
unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a);
343
unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a);
344
unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a);
345
c = SkPackARGB32(a, r, g, b);
352
virtual Factory getFactory() { return CreateProc; }
354
SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer)
355
: INHERITED(buffer) {}
358
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
360
return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer));
362
typedef SkLightingColorFilter INHERITED;
365
class SkLightingColorFilter_JustMul : public SkLightingColorFilter {
367
SkLightingColorFilter_JustMul(SkColor mul, SkColor add)
368
: INHERITED(mul, add) {}
370
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
372
unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
373
unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
374
unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
376
for (int i = 0; i < count; i++)
378
SkPMColor c = shader[i];
381
unsigned a = SkGetPackedA32(c);
382
unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR);
383
unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG);
384
unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB);
385
c = SkPackARGB32(a, r, g, b);
392
virtual Factory getFactory() { return CreateProc; }
394
SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer)
395
: INHERITED(buffer) {}
398
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
400
return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer));
403
typedef SkLightingColorFilter INHERITED;
406
class SkLightingColorFilter_SingleMul : public SkLightingColorFilter {
408
SkLightingColorFilter_SingleMul(SkColor mul, SkColor add)
409
: INHERITED(mul, add)
411
SkASSERT(SkColorGetR(add) == 0);
412
SkASSERT(SkColorGetG(add) == 0);
413
SkASSERT(SkColorGetB(add) == 0);
414
SkASSERT(SkColorGetR(mul) == SkColorGetG(mul));
415
SkASSERT(SkColorGetR(mul) == SkColorGetB(mul));
418
virtual uint32_t getFlags()
420
return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag);
423
virtual void filterSpan16(const uint16_t shader[], int count, uint16_t result[])
425
// all mul components are the same
426
unsigned scale = SkAlpha255To256(SkColorGetR(fMul));
430
*result++ = SkAlphaMulRGB16(*shader++, scale);
431
} while (--count > 0);
435
virtual Factory getFactory() { return CreateProc; }
437
SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer)
438
: INHERITED(buffer) {}
441
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
443
return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer));
446
typedef SkLightingColorFilter INHERITED;
449
class SkLightingColorFilter_NoPin : public SkLightingColorFilter {
451
SkLightingColorFilter_NoPin(SkColor mul, SkColor add)
452
: INHERITED(mul, add) {}
454
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[])
456
unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul));
457
unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul));
458
unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul));
460
unsigned addR = SkColorGetR(fAdd);
461
unsigned addG = SkColorGetG(fAdd);
462
unsigned addB = SkColorGetB(fAdd);
464
for (int i = 0; i < count; i++)
466
SkPMColor c = shader[i];
469
unsigned a = SkGetPackedA32(c);
470
unsigned scaleA = SkAlpha255To256(a);
471
unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA);
472
unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA);
473
unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA);
474
c = SkPackARGB32(a, r, g, b);
481
virtual Factory getFactory() { return CreateProc; }
483
SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer)
484
: INHERITED(buffer) {}
487
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
489
return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer));
492
typedef SkLightingColorFilter INHERITED;
495
//////////////////////////////////////////////////////////////////////////////////////
497
class SkSimpleColorFilter : public SkColorFilter {
499
void filterSpan(const SkPMColor src[], int count, SkPMColor result[])
502
memcpy(result, src, count * sizeof(SkPMColor));
505
virtual void flatten(SkFlattenableWriteBuffer& buffer)
509
virtual Factory getFactory()
514
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
516
return SkNEW(SkSimpleColorFilter);
520
SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add)
528
return SkNEW(SkSimpleColorFilter); // no change to the colors
530
return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add));
535
if (SkColorGetR(mul) == SkColorGetG(mul) &&
536
SkColorGetR(mul) == SkColorGetB(mul))
538
return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add));
542
return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add));
546
if (SkColorGetR(mul) + SkColorGetR(add) <= 255 &&
547
SkColorGetG(mul) + SkColorGetG(add) <= 255 &&
548
SkColorGetB(mul) + SkColorGetB(add) <= 255)
549
return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add));
551
return SkNEW_ARGS(SkLightingColorFilter, (mul, add));