1 /*
2  * Copyright (C) 2012 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.keyguard;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.graphics.ColorFilter;
23 import android.graphics.Paint;
24 import android.graphics.Path;
25 import android.graphics.PixelFormat;
26 import android.graphics.PorterDuff;
27 import android.graphics.PorterDuffXfermode;
28 import android.graphics.Rect;
29 import android.graphics.RectF;
30 import android.graphics.drawable.Drawable;
31 
32 class KeyguardCircleFramedDrawable extends Drawable {
33 
34     private final Bitmap mBitmap;
35     private final int mSize;
36     private final Paint mPaint;
37     private final float mShadowRadius;
38     private final float mStrokeWidth;
39     private final int mFrameColor;
40     private final int mHighlightColor;
41     private final int mFrameShadowColor;
42 
43     private float mScale;
44     private Path mFramePath;
45     private Rect mSrcRect;
46     private RectF mDstRect;
47     private RectF mFrameRect;
48     private boolean mPressed;
49 
KeyguardCircleFramedDrawable(Bitmap bitmap, int size, int frameColor, float strokeWidth, int frameShadowColor, float shadowRadius, int highlightColor)50     public KeyguardCircleFramedDrawable(Bitmap bitmap, int size,
51             int frameColor, float strokeWidth,
52             int frameShadowColor, float shadowRadius,
53             int highlightColor) {
54         super();
55         mSize = size;
56         mShadowRadius = shadowRadius;
57         mFrameColor = frameColor;
58         mFrameShadowColor = frameShadowColor;
59         mStrokeWidth = strokeWidth;
60         mHighlightColor = highlightColor;
61 
62         mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
63         final Canvas canvas = new Canvas(mBitmap);
64 
65         final int width = bitmap.getWidth();
66         final int height = bitmap.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         circleRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
72         circleRect.inset(mShadowRadius, mShadowRadius);
73 
74         final Path fillPath = new Path();
75         fillPath.addArc(circleRect, 0f, 360f);
76 
77         canvas.drawColor(0, PorterDuff.Mode.CLEAR);
78 
79         // opaque circle matte
80         mPaint = new Paint();
81         mPaint.setAntiAlias(true);
82         mPaint.setColor(Color.BLACK);
83         mPaint.setStyle(Paint.Style.FILL);
84         canvas.drawPath(fillPath, mPaint);
85 
86         // mask in the icon where the bitmap is opaque
87         mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
88         canvas.drawBitmap(bitmap, cropRect, circleRect, mPaint);
89 
90         // prepare paint for frame drawing
91         mPaint.setXfermode(null);
92 
93         mScale = 1f;
94 
95         mSrcRect = new Rect(0, 0, mSize, mSize);
96         mDstRect = new RectF(0, 0, mSize, mSize);
97         mFrameRect = new RectF(mDstRect);
98         mFramePath = new Path();
99     }
100 
reset()101     public void reset() {
102         mScale = 1f;
103         mPressed = false;
104     }
105 
106     @Override
draw(Canvas canvas)107     public void draw(Canvas canvas) {
108         // clear background
109         final float outside = Math.min(canvas.getWidth(), canvas.getHeight());
110         final float inside = mScale * outside;
111         final float pad = (outside - inside) / 2f;
112 
113         mDstRect.set(pad, pad, outside - pad, outside - pad);
114         canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
115 
116         mFrameRect.set(mDstRect);
117         mFrameRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
118         mFrameRect.inset(mShadowRadius, mShadowRadius);
119 
120         mFramePath.reset();
121         mFramePath.addArc(mFrameRect, 0f, 360f);
122 
123         // white frame
124         if (mPressed) {
125             mPaint.setStyle(Paint.Style.FILL);
126             mPaint.setColor(Color.argb((int) (0.33f * 255),
127                             Color.red(mHighlightColor),
128                             Color.green(mHighlightColor),
129                             Color.blue(mHighlightColor)));
130             canvas.drawPath(mFramePath, mPaint);
131         }
132         mPaint.setStrokeWidth(mStrokeWidth);
133         mPaint.setStyle(Paint.Style.STROKE);
134         mPaint.setColor(mPressed ? mHighlightColor : mFrameColor);
135         mPaint.setShadowLayer(mShadowRadius, 0f, 0f, mFrameShadowColor);
136         canvas.drawPath(mFramePath, mPaint);
137     }
138 
setScale(float scale)139     public void setScale(float scale) {
140         mScale = scale;
141     }
142 
getScale()143     public float getScale() {
144         return mScale;
145     }
146 
setPressed(boolean pressed)147     public void setPressed(boolean pressed) {
148         mPressed = pressed;
149     }
150 
151     @Override
getOpacity()152     public int getOpacity() {
153         return PixelFormat.TRANSLUCENT;
154     }
155 
156     @Override
setAlpha(int alpha)157     public void setAlpha(int alpha) {
158     }
159 
160     @Override
setColorFilter(ColorFilter cf)161     public void setColorFilter(ColorFilter cf) {
162     }
163 
verifyParams(float iconSize, int frameColor, float stroke, int frameShadowColor, float shadowRadius, int highlightColor)164     public boolean verifyParams(float iconSize, int frameColor, float stroke,
165             int frameShadowColor, float shadowRadius, int highlightColor) {
166         return mSize == iconSize
167                 && mFrameColor == frameColor
168                 && mStrokeWidth == stroke
169                 && mFrameShadowColor == frameShadowColor
170                 && mShadowRadius == shadowRadius
171                 && mHighlightColor == highlightColor;
172     }
173 }
174