1#include "SkPorterDuff.h" 2#include "SkXfermode.h" 3 4/* This file just exists as a compatibility layer, gluing the PorterDuff API 5 into the (extended) SkXfermode API 6 */ 7 8#define MAKE_PAIR(mode) { SkPorterDuff::k##mode##_Mode, SkXfermode::k##mode##_Mode } 9 10// this table must be in SkPorterDuff::Mode order, so it can be indexed directly 11// with a porterduff mode. 12static const struct Pair { 13 SkPorterDuff::Mode fPD; 14 SkXfermode::Mode fXF; 15} gPairs[] = { 16 MAKE_PAIR(Clear), 17 MAKE_PAIR(Src), 18 MAKE_PAIR(Dst), 19 MAKE_PAIR(SrcOver), 20 MAKE_PAIR(DstOver), 21 MAKE_PAIR(SrcIn), 22 MAKE_PAIR(DstIn), 23 MAKE_PAIR(SrcOut), 24 MAKE_PAIR(DstOut), 25 MAKE_PAIR(SrcATop), 26 MAKE_PAIR(DstATop), 27 MAKE_PAIR(Xor), 28 MAKE_PAIR(Darken), 29 MAKE_PAIR(Lighten), 30 MAKE_PAIR(Multiply), 31 MAKE_PAIR(Screen), 32 { SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode } 33}; 34 35static bool find_pdmode(SkXfermode::Mode src, SkPorterDuff::Mode* dst) { 36 const Pair* pairs = gPairs; 37 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { 38 if (pairs[i].fXF == src) { 39 if (dst) { 40 *dst = pairs[i].fPD; 41 } 42 return true; 43 } 44 } 45 return false; 46} 47 48SkXfermode::Mode SkPorterDuff::ToXfermodeMode(Mode mode) { 49 SkASSERT((unsigned)mode < SkPorterDuff::kModeCount); 50 const Pair& pair = gPairs[mode]; 51 SkASSERT(pair.fPD == mode); 52 return pair.fXF; 53} 54 55SkXfermode* SkPorterDuff::CreateXfermode(SkPorterDuff::Mode mode) { 56 const Pair& pair = gPairs[mode]; 57 SkASSERT(pair.fPD == mode); 58 return SkXfermode::Create(pair.fXF); 59} 60 61bool SkPorterDuff::IsMode(SkXfermode* xfer, Mode* pdmode) { 62 SkXfermode::Mode xfmode; 63 if (!SkXfermode::IsMode(xfer, &xfmode)) { 64 return false; 65 } 66 return find_pdmode(xfmode, pdmode); 67} 68 69SkXfermodeProc SkPorterDuff::GetXfermodeProc(Mode mode) { 70 return SkXfermode::GetProc(gPairs[mode].fXF); 71} 72 73SkXfermodeProc16 SkPorterDuff::GetXfermodeProc16(Mode mode, SkColor srcColor) { 74 return SkXfermode::GetProc16(gPairs[mode].fXF, srcColor); 75} 76 77