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 17package com.android.internal.policy.impl; 18 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; 27import android.graphics.ColorMatrixColorFilter; 28import android.graphics.Paint; 29import android.graphics.PaintFlagsDrawFilter; 30import android.graphics.PixelFormat; 31import android.graphics.PorterDuff; 32import android.graphics.Rect; 33import android.graphics.RectF; 34import android.graphics.TableMaskFilter; 35import android.graphics.Typeface; 36import android.text.Layout.Alignment; 37import android.text.StaticLayout; 38import android.text.TextPaint; 39import android.util.DisplayMetrics; 40import android.util.Log; 41import android.content.res.Resources; 42import android.content.Context; 43 44/** 45 * Various utilities shared amongst the Launcher's classes. 46 */ 47final class IconUtilities { 48 private static final String TAG = "IconUtilities"; 49 50 private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; 51 52 private int mIconWidth = -1; 53 private int mIconHeight = -1; 54 private int mIconTextureWidth = -1; 55 private int mIconTextureHeight = -1; 56 57 private final Paint mPaint = new Paint(); 58 private final Paint mBlurPaint = new Paint(); 59 private final Paint mGlowColorPressedPaint = new Paint(); 60 private final Paint mGlowColorFocusedPaint = new Paint(); 61 private final Rect mOldBounds = new Rect(); 62 private final Canvas mCanvas = new Canvas(); 63 private final DisplayMetrics mDisplayMetrics; 64 65 private int mColorIndex = 0; 66 67 public IconUtilities(Context context) { 68 final Resources resources = context.getResources(); 69 DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics(); 70 final float density = metrics.density; 71 final float blurPx = 5 * density; 72 73 mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); 74 mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2); 75 76 mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL)); 77 mGlowColorPressedPaint.setColor(0xffffc300); 78 mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 79 mGlowColorFocusedPaint.setColor(0xffff8e00); 80 mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 81 82 ColorMatrix cm = new ColorMatrix(); 83 cm.setSaturation(0.2f); 84 85 mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 86 Paint.FILTER_BITMAP_FLAG)); 87 } 88 89 public Drawable createIconDrawable(Drawable src) { 90 Bitmap scaled = createIconBitmap(src); 91 92 StateListDrawable result = new StateListDrawable(); 93 94 result.addState(new int[] { android.R.attr.state_focused }, 95 new BitmapDrawable(createSelectedBitmap(scaled, false))); 96 result.addState(new int[] { android.R.attr.state_pressed }, 97 new BitmapDrawable(createSelectedBitmap(scaled, true))); 98 result.addState(new int[0], new BitmapDrawable(scaled)); 99 100 result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight); 101 return result; 102 } 103 104 /** 105 * Returns a bitmap suitable for the all apps view. The bitmap will be a power 106 * of two sized ARGB_8888 bitmap that can be used as a gl texture. 107 */ 108 private Bitmap createIconBitmap(Drawable icon) { 109 int width = mIconWidth; 110 int height = mIconHeight; 111 112 if (icon instanceof PaintDrawable) { 113 PaintDrawable painter = (PaintDrawable) icon; 114 painter.setIntrinsicWidth(width); 115 painter.setIntrinsicHeight(height); 116 } else if (icon instanceof BitmapDrawable) { 117 // Ensure the bitmap has a density. 118 BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 119 Bitmap bitmap = bitmapDrawable.getBitmap(); 120 if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 121 bitmapDrawable.setTargetDensity(mDisplayMetrics); 122 } 123 } 124 int sourceWidth = icon.getIntrinsicWidth(); 125 int sourceHeight = icon.getIntrinsicHeight(); 126 127 if (sourceWidth > 0 && sourceWidth > 0) { 128 // There are intrinsic sizes. 129 if (width < sourceWidth || height < sourceHeight) { 130 // It's too big, scale it down. 131 final float ratio = (float) sourceWidth / sourceHeight; 132 if (sourceWidth > sourceHeight) { 133 height = (int) (width / ratio); 134 } else if (sourceHeight > sourceWidth) { 135 width = (int) (height * ratio); 136 } 137 } else if (sourceWidth < width && sourceHeight < height) { 138 // It's small, use the size they gave us. 139 width = sourceWidth; 140 height = sourceHeight; 141 } 142 } 143 144 // no intrinsic size --> use default size 145 int textureWidth = mIconTextureWidth; 146 int textureHeight = mIconTextureHeight; 147 148 final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, 149 Bitmap.Config.ARGB_8888); 150 final Canvas canvas = mCanvas; 151 canvas.setBitmap(bitmap); 152 153 final int left = (textureWidth-width) / 2; 154 final int top = (textureHeight-height) / 2; 155 156 if (false) { 157 // draw a big box for the icon for debugging 158 canvas.drawColor(sColors[mColorIndex]); 159 if (++mColorIndex >= sColors.length) mColorIndex = 0; 160 Paint debugPaint = new Paint(); 161 debugPaint.setColor(0xffcccc00); 162 canvas.drawRect(left, top, left+width, top+height, debugPaint); 163 } 164 165 mOldBounds.set(icon.getBounds()); 166 icon.setBounds(left, top, left+width, top+height); 167 icon.draw(canvas); 168 icon.setBounds(mOldBounds); 169 170 return bitmap; 171 } 172 173 private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) { 174 final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight, 175 Bitmap.Config.ARGB_8888); 176 final Canvas dest = new Canvas(result); 177 178 dest.drawColor(0, PorterDuff.Mode.CLEAR); 179 180 int[] xy = new int[2]; 181 Bitmap mask = src.extractAlpha(mBlurPaint, xy); 182 183 dest.drawBitmap(mask, xy[0], xy[1], 184 pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint); 185 186 mask.recycle(); 187 188 dest.drawBitmap(src, 0, 0, mPaint); 189 190 return result; 191 } 192} 193