1 /* 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 17 package com.android.server.policy; 18 19 import android.graphics.drawable.BitmapDrawable; 20 import android.graphics.drawable.Drawable; 21 import android.graphics.drawable.PaintDrawable; 22 import android.graphics.drawable.StateListDrawable; 23 import android.graphics.Bitmap; 24 import android.graphics.BlurMaskFilter; 25 import android.graphics.Canvas; 26 import android.graphics.ColorMatrix; 27 import android.graphics.Paint; 28 import android.graphics.PaintFlagsDrawFilter; 29 import android.graphics.PorterDuff; 30 import android.graphics.Rect; 31 import android.graphics.TableMaskFilter; 32 import android.util.DisplayMetrics; 33 import android.util.TypedValue; 34 import android.content.res.Resources; 35 import android.content.Context; 36 37 /** 38 * Various utilities shared amongst the Launcher's classes. 39 */ 40 public final class IconUtilities { 41 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 IconUtilities(Context context)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)); 70 71 TypedValue value = new TypedValue(); 72 mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute( 73 android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300); 74 mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 75 mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute( 76 android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00); 77 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 createIconDrawable(Drawable src)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 */ createIconBitmap(Drawable icon)105 public Bitmap createIconBitmap(Drawable icon) { 106 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 124 if (sourceWidth > 0 && sourceHeight > 0) { 125 // 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 createSelectedBitmap(Bitmap src, boolean pressed)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); 186 dest.setBitmap(null); 187 188 return result; 189 } 190 } 191