diff options
author | Deepanshu Gupta <deepanshu@google.com> | 2014-06-24 17:30:37 -0700 |
---|---|---|
committer | Deepanshu Gupta <deepanshu@google.com> | 2014-06-24 17:42:34 -0700 |
commit | 7a139f3fc9b8c90e4580bb3f4f8f4c90a2b8d088 (patch) | |
tree | 0750a8359d19e4ee9e30ccee6a3982196e3c05c6 | |
parent | a2c96d540659a0312c3cad9a870d90f737b4b8c1 (diff) | |
download | frameworks_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.java | 83 |
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; } } |