Merge "Update default elevation values to spec" into lmp-mr1-ub-dev
diff --git a/v4/api/current.txt b/v4/api/current.txt
index ec5ae3e..45912fb 100644
--- a/v4/api/current.txt
+++ b/v4/api/current.txt
@@ -1044,8 +1044,10 @@
     method public final android.graphics.Paint getPaint();
     method public boolean hasAntiAlias();
     method public boolean hasMipMap();
+    method public boolean isCircular();
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setCornerRadius(float);
     method public void setGravity(int);
diff --git a/v4/donut/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java b/v4/donut/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
index 7231a38..0256ebb 100644
--- a/v4/donut/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
+++ b/v4/donut/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
@@ -41,7 +41,7 @@
  */
 public abstract class RoundedBitmapDrawable extends Drawable {
     private static final int DEFAULT_PAINT_FLAGS =
-            Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
+            Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | Paint.ANTI_ALIAS_FLAG;
     Bitmap mBitmap;
     private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
     private int mGravity = Gravity.FILL;
@@ -53,8 +53,9 @@
     final RectF mDstRectF = new RectF();
 
     private boolean mApplyGravity = true;
+    private boolean mIsCircular;
 
-     // These are scaled to match the target density.
+    // These are scaled to match the target density.
     private int mBitmapWidth;
     private int mBitmapHeight;
 
@@ -217,8 +218,12 @@
 
     void updateDstRect() {
         if (mApplyGravity) {
-            gravityCompatApply(mGravity, mBitmapWidth, mBitmapHeight,
-                    getBounds(), mDstRect);
+            if (mIsCircular) {
+                final int minDimen = Math.min(mBitmapWidth, mBitmapHeight);
+                gravityCompatApply(Gravity.CENTER, minDimen, minDimen, getBounds(), mDstRect);
+            } else {
+                gravityCompatApply(mGravity, mBitmapWidth, mBitmapHeight, getBounds(), mDstRect);
+            }
             mDstRectF.set(mDstRect);
             mApplyGravity = false;
         }
@@ -266,6 +271,35 @@
     }
 
     /**
+     * Sets the image shape to circular.
+     * <p>This overwrites any calls made to {@link #setCornerRadius(float)} so far.</p>
+     * <p>Further, circular images are being placed using {@link Gravity#CENTER}.</p>
+     */
+    public void setCircular(boolean circular) {
+        mIsCircular = circular;
+        mApplyGravity = true;
+        if (circular) {
+            updateCircularCornerRadius();
+            mPaint.setShader(getDefaultShader());
+            invalidateSelf();
+        } else {
+            setCornerRadius(0);
+        }
+    }
+
+    private void updateCircularCornerRadius() {
+        final int minCircularSize = Math.min(mBitmapHeight, mBitmapWidth);
+        mCornerRadius = minCircularSize / 2;
+    }
+
+    /**
+     * @return <code>true</code> if the image is circular, else <code>false</code>.
+     */
+    public boolean isCircular() {
+        return mIsCircular;
+    }
+
+    /**
      * Sets the corner radius to be applied when drawing the bitmap.
      */
     public void setCornerRadius(float cornerRadius) {
@@ -274,7 +308,19 @@
         } else {
             mPaint.setShader(null);
         }
-        mCornerRadius = cornerRadius;
+        if (mCornerRadius != cornerRadius) {
+            invalidateSelf();
+            mCornerRadius = cornerRadius;
+        }
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        if (mIsCircular) {
+            updateCircularCornerRadius();
+            mApplyGravity = true;
+        }
     }
 
     /**
@@ -296,7 +342,7 @@
 
     @Override
     public int getOpacity() {
-        if (mGravity != Gravity.FILL) {
+        if (mGravity != Gravity.FILL || mIsCircular) {
             return PixelFormat.TRANSLUCENT;
         }
         Bitmap bm = mBitmap;
@@ -315,12 +361,19 @@
         mBitmap = bitmap;
         if (mBitmap != null) {
             computeBitmapSize();
-            mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+            mBitmapShader = getDefaultShader();
         } else {
             mBitmapWidth = mBitmapHeight = -1;
         }
     }
 
+    private BitmapShader getDefaultShader() {
+        if (mBitmapShader == null) {
+            mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+        }
+        return mBitmapShader;
+    }
+
     private static boolean isGreaterThanZero(float toCompare) {
         return Float.compare(toCompare, +0.0f) > 0;
     }