Utilities.java revision 31dd503c6aa69018e694d91724d46db49ea09327
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpackage com.android.launcher; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.Drawable; 2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.PaintDrawable; 2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.PixelFormat; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.PaintFlagsDrawFilter; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Paint; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Various utilities shared amongst the Launcher's classes. 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectfinal class Utilities { 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconWidth = -1; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconHeight = -1; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Paint sPaint = new Paint(); 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Rect sBounds = new Rect(); 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Rect sOldBounds = new Rect(); 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static Canvas sCanvas = new Canvas(); 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static { 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Paint.FILTER_BITMAP_FLAG)); 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) { 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapWidth = bitmap.getWidth(); 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapHeight = bitmap.getHeight(); 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (bitmapWidth < width || bitmapHeight < height) { 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int color = context.getResources().getColor(R.color.window_background); 5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth, 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmapHeight < height ? height : bitmapHeight, Bitmap.Config.RGB_565); 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Canvas canvas = new Canvas(centered); 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawColor(color); 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(bitmap, (width - bitmapWidth) / 2.0f, (height - bitmapHeight) / 2.0f, 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project null); 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmap = centered; 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return bitmap; 6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns a Drawable representing the thumbnail of the specified Drawable. 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The size of the thumbnail is defined by the dimension 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * android.R.dimen.launcher_application_icon_size. 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * This method is not thread-safe and should be invoked on the UI thread only. 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param icon The icon to get a thumbnail of. 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return A thumbnail for the specified icon or the icon itself if the 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * thumbnail could not be created. 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Drawable createIconThumbnail(Drawable icon, Context context) { 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (sIconWidth == -1) { 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Resources resources = context.getResources(); 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sIconWidth = sIconHeight = (int) resources.getDimension( 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project android.R.dimen.app_icon_size); 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int width = sIconWidth; 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int height = sIconHeight; 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int iconWidth = icon.getIntrinsicWidth(); 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int iconHeight = icon.getIntrinsicHeight(); 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (icon instanceof PaintDrawable) { 9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project PaintDrawable painter = (PaintDrawable) icon; 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project painter.setIntrinsicWidth(width); 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project painter.setIntrinsicHeight(height); 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (width > 0 && height > 0) { 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (width < iconWidth || height < iconHeight) { 10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float ratio = (float) iconWidth / iconHeight; 10231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (iconWidth > iconHeight) { 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project height = (int) (width / ratio); 10531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (iconHeight > iconWidth) { 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project width = (int) (height * ratio); 10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? 11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Canvas canvas = sCanvas; 11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.setBitmap(thumb); 11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Copy the old bounds to restore them later 11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // If we were to do oldBounds = icon.getBounds(), 11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // the call to setBounds() that follows would 11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // change the same instance and we would lose the 11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // old bounds 11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sOldBounds.set(icon.getBounds()); 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int x = (sIconWidth - width) / 2; 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int y = (sIconHeight - height) / 2; 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setBounds(x, y, x + width, y + height); 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.draw(canvas); 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setBounds(sOldBounds); 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon = new FastBitmapDrawable(thumb); 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (iconWidth < width && iconHeight < height) { 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap.Config c = Bitmap.Config.ARGB_8888; 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Canvas canvas = sCanvas; 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.setBitmap(thumb); 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sOldBounds.set(icon.getBounds()); 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int x = (width - iconWidth) / 2; 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int y = (height - iconHeight) / 2; 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setBounds(x, y, x + iconWidth, y + iconHeight); 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.draw(canvas); 13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setBounds(sOldBounds); 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon = new FastBitmapDrawable(thumb); 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return icon; 14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns a Bitmap representing the thumbnail of the specified Bitmap. 14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The size of the thumbnail is defined by the dimension 14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * android.R.dimen.launcher_application_icon_size. 14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * This method is not thread-safe and should be invoked on the UI thread only. 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param bitmap The bitmap to get a thumbnail of. 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return A thumbnail for the specified bitmap or the bitmap itself if the 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * thumbnail could not be created. 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context) { 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (sIconWidth == -1) { 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Resources resources = context.getResources(); 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sIconWidth = sIconHeight = (int) resources.getDimension( 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project android.R.dimen.app_icon_size); 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int width = sIconWidth; 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int height = sIconHeight; 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapWidth = bitmap.getWidth(); 16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapHeight = bitmap.getHeight(); 16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (width > 0 && height > 0 && (width < bitmapWidth || height < bitmapHeight)) { 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float ratio = (float) bitmapWidth / bitmapHeight; 17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (bitmapWidth > bitmapHeight) { 17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project height = (int) (width / ratio); 17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (bitmapHeight > bitmapWidth) { 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project width = (int) (height * ratio); 17731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap.Config c = (width == sIconWidth && height == sIconHeight) ? 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmap.getConfig() : Bitmap.Config.ARGB_8888; 18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 18231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Canvas canvas = sCanvas; 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Paint paint = sPaint; 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.setBitmap(thumb); 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project paint.setDither(false); 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project paint.setFilterBitmap(true); 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sBounds.set((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height); 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sOldBounds.set(0, 0, bitmapWidth, bitmapHeight); 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(bitmap, sOldBounds, sBounds, paint); 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return thumb; 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return bitmap; 19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 196