blob: b196dec93686b40acfb552ac79cd43f23280c319 [file] [log] [blame]
Joe Onoratoe58d1c42010-04-05 16:15:37 -05001/*
2 * Copyright (C) 2008 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
Jorim Jaggib10e33f2015-02-04 21:57:40 +010017package com.android.server.policy;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050018
19import android.graphics.drawable.BitmapDrawable;
20import android.graphics.drawable.Drawable;
21import android.graphics.drawable.PaintDrawable;
22import android.graphics.drawable.StateListDrawable;
23import android.graphics.Bitmap;
24import android.graphics.BlurMaskFilter;
25import android.graphics.Canvas;
26import android.graphics.ColorMatrix;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050027import android.graphics.Paint;
28import android.graphics.PaintFlagsDrawFilter;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050029import android.graphics.PorterDuff;
30import android.graphics.Rect;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050031import android.graphics.TableMaskFilter;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050032import android.util.DisplayMetrics;
Jeff Brown68b909d2011-12-07 16:36:01 -080033import android.util.TypedValue;
Joe Onoratoe58d1c42010-04-05 16:15:37 -050034import android.content.res.Resources;
35import android.content.Context;
36
37/**
38 * Various utilities shared amongst the Launcher's classes.
39 */
Rubin Xud0902052016-01-25 16:13:50 +000040public final class IconUtilities {
Joe Onoratoe58d1c42010-04-05 16:15:37 -050041 private static final String TAG = "IconUtilities";
42
43 private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
44
45 private int mIconWidth = -1;
46 private int mIconHeight = -1;
47 private int mIconTextureWidth = -1;
48 private int mIconTextureHeight = -1;
49
50 private final Paint mPaint = new Paint();
51 private final Paint mBlurPaint = new Paint();
52 private final Paint mGlowColorPressedPaint = new Paint();
53 private final Paint mGlowColorFocusedPaint = new Paint();
54 private final Rect mOldBounds = new Rect();
55 private final Canvas mCanvas = new Canvas();
56 private final DisplayMetrics mDisplayMetrics;
57
58 private int mColorIndex = 0;
59
60 public IconUtilities(Context context) {
61 final Resources resources = context.getResources();
62 DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics();
63 final float density = metrics.density;
64 final float blurPx = 5 * density;
65
66 mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size);
67 mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
68
69 mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
Jeff Brown68b909d2011-12-07 16:36:01 -080070
71 TypedValue value = new TypedValue();
72 mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute(
73 android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300);
Joe Onoratoe58d1c42010-04-05 16:15:37 -050074 mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
Jeff Brown68b909d2011-12-07 16:36:01 -080075 mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
76 android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
Joe Onoratoe58d1c42010-04-05 16:15:37 -050077 mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
78
79 ColorMatrix cm = new ColorMatrix();
80 cm.setSaturation(0.2f);
81
82 mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
83 Paint.FILTER_BITMAP_FLAG));
84 }
85
86 public Drawable createIconDrawable(Drawable src) {
87 Bitmap scaled = createIconBitmap(src);
88
89 StateListDrawable result = new StateListDrawable();
90
91 result.addState(new int[] { android.R.attr.state_focused },
92 new BitmapDrawable(createSelectedBitmap(scaled, false)));
93 result.addState(new int[] { android.R.attr.state_pressed },
94 new BitmapDrawable(createSelectedBitmap(scaled, true)));
95 result.addState(new int[0], new BitmapDrawable(scaled));
96
97 result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight);
98 return result;
99 }
100
101 /**
102 * Returns a bitmap suitable for the all apps view. The bitmap will be a power
103 * of two sized ARGB_8888 bitmap that can be used as a gl texture.
104 */
Rubin Xud0902052016-01-25 16:13:50 +0000105 public Bitmap createIconBitmap(Drawable icon) {
Joe Onoratoe58d1c42010-04-05 16:15:37 -0500106 int width = mIconWidth;
107 int height = mIconHeight;
108
109 if (icon instanceof PaintDrawable) {
110 PaintDrawable painter = (PaintDrawable) icon;
111 painter.setIntrinsicWidth(width);
112 painter.setIntrinsicHeight(height);
113 } else if (icon instanceof BitmapDrawable) {
114 // Ensure the bitmap has a density.
115 BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
116 Bitmap bitmap = bitmapDrawable.getBitmap();
117 if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
118 bitmapDrawable.setTargetDensity(mDisplayMetrics);
119 }
120 }
121 int sourceWidth = icon.getIntrinsicWidth();
122 int sourceHeight = icon.getIntrinsicHeight();
123
SeongJae Park8108e9f2012-07-14 14:18:51 +0900124 if (sourceWidth > 0 && sourceHeight > 0) {
Joe Onoratoe58d1c42010-04-05 16:15:37 -0500125 // There are intrinsic sizes.
126 if (width < sourceWidth || height < sourceHeight) {
127 // It's too big, scale it down.
128 final float ratio = (float) sourceWidth / sourceHeight;
129 if (sourceWidth > sourceHeight) {
130 height = (int) (width / ratio);
131 } else if (sourceHeight > sourceWidth) {
132 width = (int) (height * ratio);
133 }
134 } else if (sourceWidth < width && sourceHeight < height) {
135 // It's small, use the size they gave us.
136 width = sourceWidth;
137 height = sourceHeight;
138 }
139 }
140
141 // no intrinsic size --> use default size
142 int textureWidth = mIconTextureWidth;
143 int textureHeight = mIconTextureHeight;
144
145 final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
146 Bitmap.Config.ARGB_8888);
147 final Canvas canvas = mCanvas;
148 canvas.setBitmap(bitmap);
149
150 final int left = (textureWidth-width) / 2;
151 final int top = (textureHeight-height) / 2;
152
153 if (false) {
154 // draw a big box for the icon for debugging
155 canvas.drawColor(sColors[mColorIndex]);
156 if (++mColorIndex >= sColors.length) mColorIndex = 0;
157 Paint debugPaint = new Paint();
158 debugPaint.setColor(0xffcccc00);
159 canvas.drawRect(left, top, left+width, top+height, debugPaint);
160 }
161
162 mOldBounds.set(icon.getBounds());
163 icon.setBounds(left, top, left+width, top+height);
164 icon.draw(canvas);
165 icon.setBounds(mOldBounds);
166
167 return bitmap;
168 }
169
170 private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) {
171 final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight,
172 Bitmap.Config.ARGB_8888);
173 final Canvas dest = new Canvas(result);
174
175 dest.drawColor(0, PorterDuff.Mode.CLEAR);
176
177 int[] xy = new int[2];
178 Bitmap mask = src.extractAlpha(mBlurPaint, xy);
179
180 dest.drawBitmap(mask, xy[0], xy[1],
181 pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint);
182
183 mask.recycle();
184
185 dest.drawBitmap(src, 0, 0, mPaint);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -0700186 dest.setBitmap(null);
Joe Onoratoe58d1c42010-04-05 16:15:37 -0500187
188 return result;
189 }
190}