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