1864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani/* 2864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * Copyright (C) 2013 The Android Open Source Project 3864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * 4864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 5864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * you may not use this file except in compliance with the License. 6864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * You may obtain a copy of the License at 7864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * 8864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 9864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * 10864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * Unless required by applicable law or agreed to in writing, software 11864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 12864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * See the License for the specific language governing permissions and 14864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * limitations under the License. 15864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani */ 16864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 17fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghinapackage com.android.settings.drawable; 18864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 19864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.content.Context; 20864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.content.res.Resources; 21864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Bitmap; 22864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Canvas; 23864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Color; 24864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.ColorFilter; 25864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Paint; 26864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Path; 27864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.PixelFormat; 28864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.PorterDuff; 29864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.PorterDuffXfermode; 30864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.Rect; 31864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.RectF; 32864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport android.graphics.drawable.Drawable; 33864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 34864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasaniimport com.android.settings.R; 35864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 36864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani/** 37864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * Converts the user avatar icon to a circularly clipped one. 38864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani * TODO: Move this to an internal framework class and share with the one in Keyguard. 39864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani */ 4095b86a5488a27d95bda8b6db1f608d6ce55dae8aAlexandra Gherghinapublic class CircleFramedDrawable extends Drawable { 41864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 42864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private final Bitmap mBitmap; 43864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private final int mSize; 44864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private final Paint mPaint; 45864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 46864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private float mScale; 47864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private Rect mSrcRect; 48864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani private RectF mDstRect; 49864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 50864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public static CircleFramedDrawable getInstance(Context context, Bitmap icon) { 51864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani Resources res = context.getResources(); 52864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani float iconSize = res.getDimension(R.dimen.circle_avatar_size); 53ae6ea36822dca031facb1c502aa9d527ceba658cZoltan Szatmary-Ban 54ae6ea36822dca031facb1c502aa9d527ceba658cZoltan Szatmary-Ban CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize); 55864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani return instance; 56864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 57864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 58ae6ea36822dca031facb1c502aa9d527ceba658cZoltan Szatmary-Ban public CircleFramedDrawable(Bitmap icon, int size) { 59864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani super(); 60864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mSize = size; 61864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 62864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888); 63864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final Canvas canvas = new Canvas(mBitmap); 64864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 65864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final int width = icon.getWidth(); 66864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final int height = icon.getHeight(); 67864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final int square = Math.min(width, height); 68864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 69864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square); 70864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final RectF circleRect = new RectF(0f, 0f, mSize, mSize); 71864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 72864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani final Path fillPath = new Path(); 73864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani fillPath.addArc(circleRect, 0f, 360f); 74864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 75864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani canvas.drawColor(0, PorterDuff.Mode.CLEAR); 76864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 77864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani // opaque circle matte 78864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mPaint = new Paint(); 79864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mPaint.setAntiAlias(true); 80864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mPaint.setColor(Color.BLACK); 81864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mPaint.setStyle(Paint.Style.FILL); 82864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani canvas.drawPath(fillPath, mPaint); 83864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 84864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani // mask in the icon where the bitmap is opaque 85bc6e78f9da195af4c3a936bff22773ce867af0aaAlexandra Gherghina mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 86864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani canvas.drawBitmap(icon, cropRect, circleRect, mPaint); 87864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 88864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani // prepare paint for frame drawing 89864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mPaint.setXfermode(null); 90864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 91864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mScale = 1f; 92864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 93864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mSrcRect = new Rect(0, 0, mSize, mSize); 94864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mDstRect = new RectF(0, 0, mSize, mSize); 95864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 96864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 97864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani @Override 98864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public void draw(Canvas canvas) { 998397ba603c9eacbd095a15478d60d5f7b85845a8Svetoslav final float inside = mScale * mSize; 1008397ba603c9eacbd095a15478d60d5f7b85845a8Svetoslav final float pad = (mSize - inside) / 2f; 101864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 1028397ba603c9eacbd095a15478d60d5f7b85845a8Svetoslav mDstRect.set(pad, pad, mSize - pad, mSize - pad); 103864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null); 104864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 105864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 106864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public void setScale(float scale) { 107864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani mScale = scale; 108864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 109864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 110864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public float getScale() { 111864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani return mScale; 112864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 113864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 114864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani @Override 115864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public int getOpacity() { 116864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani return PixelFormat.TRANSLUCENT; 117864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 118864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 119864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani @Override 120864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public void setAlpha(int alpha) { 121864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 122864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani 123864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani @Override 124864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani public void setColorFilter(ColorFilter cf) { 125864e3b7c5176199f7f0fae53c2639f9dacd737e2Amith Yamasani } 126bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav 127bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav @Override 128bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav public int getIntrinsicWidth() { 129bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav return mSize; 130bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav } 131bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav 132bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav @Override 133bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav public int getIntrinsicHeight() { 134bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav return mSize; 135bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav } 136bf3391f19b6f1733825de07d9c602545f8818c64Svetoslav} 137