11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkBlitRow.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#define ILLEGAL_XFERMODE_MODE ((SkXfermode::Mode)-1) 1635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger// baseclass for filters that store a color and mode 1835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SkModeColorFilter : public SkColorFilter { 1935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerpublic: 2035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkModeColorFilter(SkColor color) { 2135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fColor = color; 2235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fMode = ILLEGAL_XFERMODE_MODE; 2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 2435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fPMColor = SkPreMultiplyColor(fColor); 2535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 2635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 2735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkModeColorFilter(SkColor color, SkXfermode::Mode mode) { 2835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fColor = color; 2935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fMode = mode; 3035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fPMColor = SkPreMultiplyColor(fColor); 3235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger }; 3335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) { 3535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (ILLEGAL_XFERMODE_MODE == fMode) { 3635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 3735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 3835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (color) { 4035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger *color = fColor; 4135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 4235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mode) { 4335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger *mode = fMode; 4435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 4535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return true; 4635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkColor getColor() const { return fColor; } 4935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkXfermode::Mode getMode() const { return fMode; } 5035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; } 5135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 5235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprotected: 5359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void flatten(SkFlattenableWriteBuffer& buffer) { 5435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->INHERITED::flatten(buffer); 5535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger buffer.write32(fColor); 5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger buffer.write32(fMode); 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed 5935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkModeColorFilter(SkFlattenableReadBuffer& buffer) { 6035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fColor = buffer.readU32(); 6135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fMode = (SkXfermode::Mode)buffer.readU32(); 6235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 6335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fPMColor = SkPreMultiplyColor(fColor); 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed 6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // cache of fColor in premultiply space 6759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor fPMColor; 6835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 6935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 7035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkColor fColor; 7135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkXfermode::Mode fMode; 7235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 7335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger typedef SkColorFilter INHERITED; 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass Src_SkModeColorFilter : public SkModeColorFilter { 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 7835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual uint32_t getFlags() { 8159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (SkGetPackedA32(fPMColor) == 0xFF) { 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return kAlphaUnchanged_Flag | kHasFilter16_Flag; 8359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else { 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 8559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 8959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 9059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed sk_memset32(result, fPMColor, count); 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan16(const uint16_t shader[], int count, 9459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed uint16_t result[]) { 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->getFlags() & kHasFilter16_Flag); 9659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed sk_memset16(result, SkPixel32ToPixel16(fPMColor), count); 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 10035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(Src_SkModeColorFilter, (buffer)); 10135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 10235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 10759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed : INHERITED(buffer) {} 10859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed 10935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 11035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger typedef SkModeColorFilter INHERITED; 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SrcOver_SkModeColorFilter : public SkModeColorFilter { 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 11535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SrcOver_SkModeColorFilter(SkColor color) 11635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : INHERITED(color, SkXfermode::kSrcOver_Mode) { 11735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fColor32Proc = NULL; 11835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual uint32_t getFlags() { 12159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (SkGetPackedA32(fPMColor) == 0xFF) { 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return kAlphaUnchanged_Flag | kHasFilter16_Flag; 12359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else { 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 12559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 12859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 12959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 13035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (NULL == fColor32Proc) { 13135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fColor32Proc = SkBlitRow::ColorProcFactory(); 13235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 13340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fColor32Proc(result, shader, count, fPMColor); 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan16(const uint16_t shader[], int count, 13759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed uint16_t result[]) { 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->getFlags() & kHasFilter16_Flag); 13959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed sk_memset16(result, SkPixel32ToPixel16(fPMColor), count); 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 14235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 14335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SrcOver_SkModeColorFilter, (buffer)); 14435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 14535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 14835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 14935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 15035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : INHERITED(buffer), fColor32Proc(NULL) {} 15135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 15335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBlitRow::ColorProc fColor32Proc; 15535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger typedef SkModeColorFilter INHERITED; 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass Proc_SkModeColorFilter : public SkModeColorFilter { 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 16335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Proc_SkModeColorFilter(SkColor color, SkXfermode::Mode mode) : INHERITED(color, mode) { 16435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fProc = SkXfermode::GetProc(mode); 16535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fProc16 = SkXfermode::GetProc16(mode, color); 16635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 16735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 16835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Proc_SkModeColorFilter(SkColor color, 16935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkXfermodeProc proc, SkXfermodeProc16 proc16) 17035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : INHERITED(color, ILLEGAL_XFERMODE_MODE) { 1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc = proc; 1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc16 = proc16; 1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 17435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual uint32_t getFlags() { 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0; 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 18059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 18159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor color = fPMColor; 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc proc = fProc; 18359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed 18459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = proc(color, shader[i]); 18659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 18835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 18959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan16(const uint16_t shader[], int count, 19059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed uint16_t result[]) { 1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->getFlags() & kHasFilter16_Flag); 19235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 19359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor color = fPMColor; 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 proc16 = fProc16; 19535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 19659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = proc16(color, shader[i]); 19859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 20135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 20235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(Proc_SkModeColorFilter, (buffer)); 20335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 20435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual void flatten(SkFlattenableWriteBuffer& buffer) { 2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(buffer); 2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFunctionPtr((void*)fProc); 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFunctionPtr((void*)fProc16); 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 21235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger virtual Factory getFactory() { 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Proc_SkModeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc = (SkXfermodeProc) buffer.readFunctionPtr(); 2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr(); 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc fProc; 2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 fProc16; 22435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 22535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger typedef SkModeColorFilter INHERITED; 2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateProcFilter(SkColor color, 22959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermodeProc proc, 23059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermodeProc16 proc16) { 2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return proc ? 23235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkNEW_ARGS(Proc_SkModeColorFilter, (color, proc, proc16)) : 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL; 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, 23959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::Mode mode) { 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned alpha = SkColorGetA(color); 2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // first collaps some modes if possible 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (SkXfermode::kClear_Mode == mode) { 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project color = 0; 24659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed mode = SkXfermode::kSrc_Mode; 24759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else if (SkXfermode::kSrcOver_Mode == mode) { 24859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (0 == alpha) { 24959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed mode = SkXfermode::kDst_Mode; 25059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else if (255 == alpha) { 25159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed mode = SkXfermode::kSrc_Mode; 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // else just stay srcover 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // weed out combinations that are noops, and just return null 25759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (SkXfermode::kDst_Mode == mode || 25859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed (0 == alpha && (SkXfermode::kSrcOver_Mode == mode || 25959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::kDstOver_Mode == mode || 26059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::kDstOut_Mode == mode || 26159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::kSrcATop_Mode == mode || 26259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::kXor_Mode == mode || 26359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::kDarken_Mode == mode)) || 26459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) { 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 26735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (mode) { 26935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case SkXfermode::kSrc_Mode: 27035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(Src_SkModeColorFilter, (color)); 27135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger case SkXfermode::kSrcOver_Mode: 27235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color)); 27335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger default: 27435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(Proc_SkModeColorFilter, (color, mode)); 2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed/////////////////////////////////////////////////////////////////////////////// 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 28059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reedstatic inline unsigned pin(unsigned value, unsigned max) { 28159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (value > max) { 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project value = max; 28359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value; 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 28759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reedstatic inline unsigned SkUClampMax(unsigned value, unsigned max) { 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int32_t)value >= 0); 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((int32_t)max >= 0); 2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int diff = max - value; 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // clear diff if diff is positive 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project diff &= diff >> 31; 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value + diff; 2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter : public SkColorFilter { 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {} 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 30259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 30359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 30735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addR = SkColorGetR(fAdd); 3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addG = SkColorGetG(fAdd); 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addB = SkColorGetB(fAdd); 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 31259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor c = shader[i]; 31459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (c) { 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(c); 31635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger unsigned scaleA = SkAlpha255To256(a); 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a); 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a); 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a); 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project c = SkPackARGB32(a, r, g, b); 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = c; 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkLightingColorFilter, (buffer)); 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 33159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void flatten(SkFlattenableWriteBuffer& buffer) { 33235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger this->INHERITED::flatten(buffer); 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fMul); 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fAdd); 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 33635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 33759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual Factory getFactory() { 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkLightingColorFilter(SkFlattenableReadBuffer& buffer) { 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMul = buffer.readU32(); 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fAdd = buffer.readU32(); 3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 34535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkColor fMul, fAdd; 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 34935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger typedef SkColorFilter INHERITED; 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_JustAdd : public SkLightingColorFilter { 3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_JustAdd(SkColor mul, SkColor add) 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(mul, add) {} 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 35859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addR = SkColorGetR(fAdd); 3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addG = SkColorGetG(fAdd); 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addB = SkColorGetB(fAdd); 3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 36359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor c = shader[i]; 36559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (c) { 3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(c); 36735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger unsigned scaleA = SkAlpha255To256(a); 3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a); 3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a); 3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a); 3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project c = SkPackARGB32(a, r, g, b); 3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = c; 3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer)); 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer) 3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(buffer) {} 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkLightingColorFilter INHERITED; 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_JustMul : public SkLightingColorFilter { 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_JustMul(SkColor mul, SkColor add) 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(mul, add) {} 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 39759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 40135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 40259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor c = shader[i]; 40459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (c) { 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(c); 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR); 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG); 4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB); 4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project c = SkPackARGB32(a, r, g, b); 4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = c; 4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer)); 4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer) 4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(buffer) {} 42435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkLightingColorFilter INHERITED; 4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_SingleMul : public SkLightingColorFilter { 4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_SingleMul(SkColor mul, SkColor add) 43259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed : INHERITED(mul, add) { 4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkColorGetR(add) == 0); 4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkColorGetG(add) == 0); 4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkColorGetB(add) == 0); 4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkColorGetR(mul) == SkColorGetG(mul)); 4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkColorGetR(mul) == SkColorGetB(mul)); 4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 43935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 44059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual uint32_t getFlags() { 4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag); 4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 44459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan16(const uint16_t shader[], int count, 44559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed uint16_t result[]) { 4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // all mul components are the same 4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scale = SkAlpha255To256(SkColorGetR(fMul)); 4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 44959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (count > 0) { 4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *result++ = SkAlphaMulRGB16(*shader++, scale); 4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--count > 0); 45359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer)); 4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer) 4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(buffer) {} 4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkLightingColorFilter INHERITED; 4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkLightingColorFilter_NoPin : public SkLightingColorFilter { 4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_NoPin(SkColor mul, SkColor add) 4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(mul, add) {} 47435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 47559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void filterSpan(const SkPMColor shader[], int count, 47659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkPMColor result[]) { 4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 48035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addR = SkColorGetR(fAdd); 4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addG = SkColorGetG(fAdd); 4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned addB = SkColorGetB(fAdd); 48435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 48559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed for (int i = 0; i < count; i++) { 4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor c = shader[i]; 48759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (c) { 4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(c); 48935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger unsigned scaleA = SkAlpha255To256(a); 4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA); 4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA); 4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA); 4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project c = SkPackARGB32(a, r, g, b); 4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project result[i] = c; 4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 49835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer)); 5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project virtual Factory getFactory() { return CreateProc; } 50535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer) 5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : INHERITED(buffer) {} 50835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkLightingColorFilter INHERITED; 5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 51359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed/////////////////////////////////////////////////////////////////////////////// 5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkSimpleColorFilter : public SkColorFilter { 5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic: 5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW(SkSimpleColorFilter); 5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 52259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) { 52359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (result != src) { 5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(result, src, count * sizeof(SkPMColor)); 52559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 52859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual void flatten(SkFlattenableWriteBuffer& buffer) {} 52935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 53059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed virtual Factory getFactory() { 5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 53659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) { 5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mul &= 0x00FFFFFF; 5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add &= 0x00FFFFFF; 5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 54059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (0xFFFFFF == mul) { 54159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (0 == add) { 5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW(SkSimpleColorFilter); // no change to the colors 54359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else { 5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add)); 54559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 54859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed if (0 == add) { 5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (SkColorGetR(mul) == SkColorGetG(mul) && 55059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkColorGetR(mul) == SkColorGetB(mul)) { 5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add)); 55259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } else { 5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add)); 5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (SkColorGetR(mul) + SkColorGetR(add) <= 255 && 5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkColorGetG(mul) + SkColorGetG(add) <= 255 && 55959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkColorGetB(mul) + SkColorGetB(add) <= 255) { 56059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add)); 56159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed } 5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkLightingColorFilter, (mul, add)); 5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5661cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Proc_SkModeColorFilter) 5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) 5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) 5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) 5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) 5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) 5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) 5761cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 57735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 578