summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepanshu Gupta <deepanshu@google.com>2014-06-24 17:30:37 -0700
committerDeepanshu Gupta <deepanshu@google.com>2014-06-24 17:42:34 -0700
commit7a139f3fc9b8c90e4580bb3f4f8f4c90a2b8d088 (patch)
tree0750a8359d19e4ee9e30ccee6a3982196e3c05c6
parenta2c96d540659a0312c3cad9a870d90f737b4b8c1 (diff)
downloadframeworks_base-7a139f3fc9b8c90e4580bb3f4f8f4c90a2b8d088.zip
frameworks_base-7a139f3fc9b8c90e4580bb3f4f8f4c90a2b8d088.tar.gz
frameworks_base-7a139f3fc9b8c90e4580bb3f4f8f4c90a2b8d088.tar.bz2
Improve PorterDuff support.
1. Don't cache the src image used for applying the filter. The filter delegate is not always cleared. This probably results in slighly slower rendering, but doesn't run Studio out of memory. 2. Support more PorterDuff modes. 3. Fix a bug where the alpha was applied twice and thus the filter had less effect than it should have had. Change-Id: I2a481a64ba7f1ff8e9683bbc46ae110433e82ebc
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java83
1 files changed, 50 insertions, 33 deletions
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
index c44e03b..ee90595 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
@@ -51,25 +51,13 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
private final int mSrcColor;
private final Mode mMode;
- private int mWidth;
- private int mHeight;
- private BufferedImage mImage;
// ---- Public Helper methods ----
@Override
public boolean isSupported() {
- switch (mMode) {
- case CLEAR:
- case SRC:
- case SRC_IN:
- case DST_IN:
- case SRC_ATOP:
- return true;
- }
-
- return false;
+ return getAlphaCompositeRule(mMode) != -1;
}
@Override
@@ -79,9 +67,9 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
@Override
public void applyFilter(Graphics2D g, int width, int height) {
- createFilterImage(width, height);
+ BufferedImage image = createFilterImage(width, height);
g.setComposite(getComposite());
- g.drawImage(mImage, 0, 0, null);
+ g.drawImage(image, 0, 0, null);
}
// ---- native methods ----
@@ -98,36 +86,65 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
private PorterDuffColorFilter_Delegate(int srcColor, int mode) {
mSrcColor = srcColor;
- // Temporarily change multiply to SRC_IN to render menus.
- // TODO: support Mode.MULTIPLY
- if (mode == Mode.MULTIPLY.nativeInt) {
- mode = Mode.SRC_IN.nativeInt;
- }
- mMode = getPorterDuffMode(mode);
+ mMode = getCompatibleMode(getPorterDuffMode(mode));
}
- private void createFilterImage(int width, int height) {
- if (mWidth == width && mHeight == height && mImage != null) {
- return;
- }
- mWidth = width;
- mHeight = height;
- mImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D graphics = mImage.createGraphics();
+ private BufferedImage createFilterImage(int width, int height) {
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = image.createGraphics();
try {
graphics.setColor(new java.awt.Color(mSrcColor, true /* hasAlpha */));
graphics.fillRect(0, 0, width, height);
} finally {
graphics.dispose();
}
+ return image;
}
private AlphaComposite getComposite() {
- return AlphaComposite.getInstance(getAlphaCompositeRule(mMode),
- getAlpha() / 255f);
+ return AlphaComposite.getInstance(getAlphaCompositeRule(mMode));
}
- private int getAlpha() {
- return mSrcColor >>> 24;
+ // For filtering the colors, the src image should contain the "color" only for pixel values
+ // which are not transparent in the target image. But, we are using a simple rectangular image
+ // completely filled with color. Hence some AlphaComposite rules do not apply as intended.
+ // However, in such cases, they can usually be mapped to some other mode, which produces an
+ // equivalent result.
+ private Mode getCompatibleMode(Mode mode) {
+ Mode m = mode;
+ switch (mode) {
+ // Modes that are directly supported.
+ case CLEAR:
+ case DST:
+ case SRC_IN:
+ case DST_IN:
+ case DST_OUT:
+ case SRC_ATOP:
+ break;
+ // Modes that can be mapped to one of the supported modes.
+ case SRC:
+ m = Mode.SRC_IN;
+ break;
+ case SRC_OVER:
+ m = Mode.SRC_ATOP;
+ break;
+ case DST_OVER:
+ m = Mode.DST;
+ break;
+ case SRC_OUT:
+ m = Mode.CLEAR;
+ break;
+ case DST_ATOP:
+ m = Mode.DST_IN;
+ break;
+ case XOR:
+ m = Mode.DST_OUT;
+ break;
+ // This mode is not supported, but used by Action Bar Overflow Popup Menus. We map this
+ // to the closest supported mode, to prevent showing excessive warnings to the user.
+ case MULTIPLY:
+ m = Mode.SRC_IN;
+ }
+ return m;
}
}