1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.layoutlib.bridge.impl;
18
19import com.android.ide.common.rendering.api.LayoutLog;
20import com.android.layoutlib.bridge.Bridge;
21
22import android.graphics.BlendComposite;
23import android.graphics.BlendComposite.BlendingMode;
24import android.graphics.PorterDuff;
25import android.graphics.PorterDuff.Mode;
26import android.graphics.PorterDuffColorFilter_Delegate;
27
28import java.awt.AlphaComposite;
29import java.awt.Composite;
30
31/**
32 * Provides various utility methods for {@link PorterDuffColorFilter_Delegate}.
33 */
34public final class PorterDuffUtility {
35
36    private static final int MODES_COUNT = Mode.values().length;
37
38    // Make the class non-instantiable.
39    private PorterDuffUtility() {
40    }
41
42    /**
43     * Convert the porterDuffMode from the framework to its corresponding enum. This defaults to
44     * {@link Mode#SRC_OVER} for invalid modes.
45     */
46    public static Mode getPorterDuffMode(int porterDuffMode) {
47        if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
48            return PorterDuff.intToMode(porterDuffMode);
49        }
50        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
51                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null);
52        assert false;
53        return Mode.SRC_OVER;
54    }
55
56    /**
57     * A utility method to get the {@link Composite} that represents the filter for the given
58     * PorterDuff mode and the alpha. Defaults to {@link Mode#SRC_OVER} for invalid modes.
59     */
60    public static Composite getComposite(Mode mode, int alpha255) {
61        float alpha1 = alpha255 != 0xFF ? alpha255 / 255.f : 1.f;
62        switch (mode) {
63            case CLEAR:
64                return AlphaComposite.getInstance(AlphaComposite.CLEAR, alpha1);
65            case SRC:
66                return AlphaComposite.getInstance(AlphaComposite.SRC, alpha1);
67            case DST:
68                return AlphaComposite.getInstance(AlphaComposite.DST, alpha1);
69            case SRC_OVER:
70                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
71            case DST_OVER:
72                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, alpha1);
73            case SRC_IN:
74                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha1);
75            case DST_IN:
76                return AlphaComposite.getInstance(AlphaComposite.DST_IN, alpha1);
77            case SRC_OUT:
78                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, alpha1);
79            case DST_OUT:
80                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, alpha1);
81            case SRC_ATOP:
82                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha1);
83            case DST_ATOP:
84                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, alpha1);
85            case XOR:
86                return AlphaComposite.getInstance(AlphaComposite.XOR, alpha1);
87            case DARKEN:
88                return BlendComposite.getInstance(BlendingMode.DARKEN, alpha1);
89            case LIGHTEN:
90                return BlendComposite.getInstance(BlendingMode.LIGHTEN, alpha1);
91            case MULTIPLY:
92                return BlendComposite.getInstance(BlendingMode.MULTIPLY, alpha1);
93            case SCREEN:
94                return BlendComposite.getInstance(BlendingMode.SCREEN, alpha1);
95            case ADD:
96                return BlendComposite.getInstance(BlendingMode.ADD, alpha1);
97            case OVERLAY:
98                return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1);
99            default:
100                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
101                        String.format("Unsupported PorterDuff Mode: %1$s", mode.name()),
102                        null, null /*data*/);
103
104                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
105        }
106    }
107}
108