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 
17 package com.android.layoutlib.bridge.impl;
18 
19 import com.android.ide.common.rendering.api.LayoutLog;
20 import com.android.layoutlib.bridge.Bridge;
21 
22 import android.graphics.BlendComposite;
23 import android.graphics.BlendComposite.BlendingMode;
24 import android.graphics.PorterDuff;
25 import android.graphics.PorterDuff.Mode;
26 import android.graphics.PorterDuffColorFilter_Delegate;
27 
28 import java.awt.AlphaComposite;
29 import java.awt.Composite;
30 
31 /**
32  * Provides various utility methods for {@link PorterDuffColorFilter_Delegate}.
33  */
34 public final class PorterDuffUtility {
35 
36     private static final int MODES_COUNT = Mode.values().length;
37 
38     // Make the class non-instantiable.
PorterDuffUtility()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      */
getPorterDuffMode(int porterDuffMode)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      */
getComposite(Mode mode, int alpha255)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