1 /* 2 * Copyright (C) 2013 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.settingslib.drawable; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.graphics.Bitmap; 22 import android.graphics.Canvas; 23 import android.graphics.Color; 24 import android.graphics.ColorFilter; 25 import android.graphics.Paint; 26 import android.graphics.Path; 27 import android.graphics.PixelFormat; 28 import android.graphics.PorterDuff; 29 import android.graphics.PorterDuffXfermode; 30 import android.graphics.Rect; 31 import android.graphics.RectF; 32 import android.graphics.drawable.Drawable; 33 34 import com.android.settingslib.R; 35 36 /** 37 * Converts the user avatar icon to a circularly clipped one. 38 * TODO: Move this to an internal framework class and share with the one in Keyguard. 39 */ 40 public class CircleFramedDrawable extends Drawable { 41 42 private final Bitmap mBitmap; 43 private final int mSize; 44 private final Paint mPaint; 45 46 private float mScale; 47 private Rect mSrcRect; 48 private RectF mDstRect; 49 getInstance(Context context, Bitmap icon)50 public static CircleFramedDrawable getInstance(Context context, Bitmap icon) { 51 Resources res = context.getResources(); 52 float iconSize = res.getDimension(R.dimen.circle_avatar_size); 53 54 CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize); 55 return instance; 56 } 57 CircleFramedDrawable(Bitmap icon, int size)58 public CircleFramedDrawable(Bitmap icon, int size) { 59 super(); 60 mSize = size; 61 62 mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888); 63 final Canvas canvas = new Canvas(mBitmap); 64 65 final int width = icon.getWidth(); 66 final int height = icon.getHeight(); 67 final int square = Math.min(width, height); 68 69 final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square); 70 final RectF circleRect = new RectF(0f, 0f, mSize, mSize); 71 72 final Path fillPath = new Path(); 73 fillPath.addArc(circleRect, 0f, 360f); 74 75 canvas.drawColor(0, PorterDuff.Mode.CLEAR); 76 77 // opaque circle matte 78 mPaint = new Paint(); 79 mPaint.setAntiAlias(true); 80 mPaint.setColor(Color.BLACK); 81 mPaint.setStyle(Paint.Style.FILL); 82 canvas.drawPath(fillPath, mPaint); 83 84 // mask in the icon where the bitmap is opaque 85 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 86 canvas.drawBitmap(icon, cropRect, circleRect, mPaint); 87 88 // prepare paint for frame drawing 89 mPaint.setXfermode(null); 90 91 mScale = 1f; 92 93 mSrcRect = new Rect(0, 0, mSize, mSize); 94 mDstRect = new RectF(0, 0, mSize, mSize); 95 } 96 97 @Override draw(Canvas canvas)98 public void draw(Canvas canvas) { 99 final float inside = mScale * mSize; 100 final float pad = (mSize - inside) / 2f; 101 102 mDstRect.set(pad, pad, mSize - pad, mSize - pad); 103 canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null); 104 } 105 setScale(float scale)106 public void setScale(float scale) { 107 mScale = scale; 108 } 109 getScale()110 public float getScale() { 111 return mScale; 112 } 113 114 @Override getOpacity()115 public int getOpacity() { 116 return PixelFormat.TRANSLUCENT; 117 } 118 119 @Override setAlpha(int alpha)120 public void setAlpha(int alpha) { 121 } 122 123 @Override setColorFilter(ColorFilter cf)124 public void setColorFilter(ColorFilter cf) { 125 } 126 127 @Override getIntrinsicWidth()128 public int getIntrinsicWidth() { 129 return mSize; 130 } 131 132 @Override getIntrinsicHeight()133 public int getIntrinsicHeight() { 134 return mSize; 135 } 136 } 137