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
17package com.android.settingslib.drawable;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Bitmap;
22import android.graphics.Canvas;
23import android.graphics.Color;
24import android.graphics.ColorFilter;
25import android.graphics.Paint;
26import android.graphics.Path;
27import android.graphics.PixelFormat;
28import android.graphics.PorterDuff;
29import android.graphics.PorterDuffXfermode;
30import android.graphics.Rect;
31import android.graphics.RectF;
32import android.graphics.drawable.Drawable;
33
34import 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 */
40public 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
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
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
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
106    public void setScale(float scale) {
107        mScale = scale;
108    }
109
110    public float getScale() {
111        return mScale;
112    }
113
114    @Override
115    public int getOpacity() {
116        return PixelFormat.TRANSLUCENT;
117    }
118
119    @Override
120    public void setAlpha(int alpha) {
121    }
122
123    @Override
124    public void setColorFilter(ColorFilter cf) {
125    }
126
127    @Override
128    public int getIntrinsicWidth() {
129        return mSize;
130    }
131
132    @Override
133    public int getIntrinsicHeight() {
134        return mSize;
135    }
136}
137