/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.policy.impl; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.PaintDrawable; import android.graphics.drawable.StateListDrawable; import android.graphics.Bitmap; import android.graphics.BlurMaskFilter; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.TableMaskFilter; import android.graphics.Typeface; import android.text.Layout.Alignment; import android.text.StaticLayout; import android.text.TextPaint; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.content.res.Resources; import android.content.Context; /** * Various utilities shared amongst the Launcher's classes. */ final class IconUtilities { private static final String TAG = "IconUtilities"; private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; private int mIconWidth = -1; private int mIconHeight = -1; private int mIconTextureWidth = -1; private int mIconTextureHeight = -1; private final Paint mPaint = new Paint(); private final Paint mBlurPaint = new Paint(); private final Paint mGlowColorPressedPaint = new Paint(); private final Paint mGlowColorFocusedPaint = new Paint(); private final Rect mOldBounds = new Rect(); private final Canvas mCanvas = new Canvas(); private final DisplayMetrics mDisplayMetrics; private int mColorIndex = 0; public IconUtilities(Context context) { final Resources resources = context.getResources(); DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics(); final float density = metrics.density; final float blurPx = 5 * density; mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2); mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL)); TypedValue value = new TypedValue(); mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute( android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300); mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute( android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00); mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0.2f); mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); } public Drawable createIconDrawable(Drawable src) { Bitmap scaled = createIconBitmap(src); StateListDrawable result = new StateListDrawable(); result.addState(new int[] { android.R.attr.state_focused }, new BitmapDrawable(createSelectedBitmap(scaled, false))); result.addState(new int[] { android.R.attr.state_pressed }, new BitmapDrawable(createSelectedBitmap(scaled, true))); result.addState(new int[0], new BitmapDrawable(scaled)); result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight); return result; } /** * Returns a bitmap suitable for the all apps view. The bitmap will be a power * of two sized ARGB_8888 bitmap that can be used as a gl texture. */ private Bitmap createIconBitmap(Drawable icon) { int width = mIconWidth; int height = mIconHeight; if (icon instanceof PaintDrawable) { PaintDrawable painter = (PaintDrawable) icon; painter.setIntrinsicWidth(width); painter.setIntrinsicHeight(height); } else if (icon instanceof BitmapDrawable) { // Ensure the bitmap has a density. BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; Bitmap bitmap = bitmapDrawable.getBitmap(); if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { bitmapDrawable.setTargetDensity(mDisplayMetrics); } } int sourceWidth = icon.getIntrinsicWidth(); int sourceHeight = icon.getIntrinsicHeight(); if (sourceWidth > 0 && sourceHeight > 0) { // There are intrinsic sizes. if (width < sourceWidth || height < sourceHeight) { // It's too big, scale it down. final float ratio = (float) sourceWidth / sourceHeight; if (sourceWidth > sourceHeight) { height = (int) (width / ratio); } else if (sourceHeight > sourceWidth) { width = (int) (height * ratio); } } else if (sourceWidth < width && sourceHeight < height) { // It's small, use the size they gave us. width = sourceWidth; height = sourceHeight; } } // no intrinsic size --> use default size int textureWidth = mIconTextureWidth; int textureHeight = mIconTextureHeight; final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, Bitmap.Config.ARGB_8888); final Canvas canvas = mCanvas; canvas.setBitmap(bitmap); final int left = (textureWidth-width) / 2; final int top = (textureHeight-height) / 2; if (false) { // draw a big box for the icon for debugging canvas.drawColor(sColors[mColorIndex]); if (++mColorIndex >= sColors.length) mColorIndex = 0; Paint debugPaint = new Paint(); debugPaint.setColor(0xffcccc00); canvas.drawRect(left, top, left+width, top+height, debugPaint); } mOldBounds.set(icon.getBounds()); icon.setBounds(left, top, left+width, top+height); icon.draw(canvas); icon.setBounds(mOldBounds); return bitmap; } private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) { final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight, Bitmap.Config.ARGB_8888); final Canvas dest = new Canvas(result); dest.drawColor(0, PorterDuff.Mode.CLEAR); int[] xy = new int[2]; Bitmap mask = src.extractAlpha(mBlurPaint, xy); dest.drawBitmap(mask, xy[0], xy[1], pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint); mask.recycle(); dest.drawBitmap(src, 0, 0, mPaint); dest.setBitmap(null); return result; } }