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