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