Utilities.java revision eb8325a9e24cda47720152e1e95f5d86ab11f200
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 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19583ed3ba08644912ec0f3ec8ceb939f9eb0b8e86Mitsuru Oshimaimport android.graphics.drawable.BitmapDrawable; 2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.Drawable; 2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.PaintDrawable; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 231291a8c236c84451321438cb68855f6f2eb24959Joe Onoratoimport android.graphics.BlurMaskFilter; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 25cdd117935f51d66f6f212387300d851f81aa071fMike Reedimport android.graphics.MaskFilter; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Paint; 27bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.PaintFlagsDrawFilter; 28bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.PixelFormat; 291291a8c236c84451321438cb68855f6f2eb24959Joe Onoratoimport android.graphics.PorterDuff; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 31bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.RectF; 32cdd117935f51d66f6f212387300d851f81aa071fMike Reedimport android.graphics.TableMaskFilter; 33bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.graphics.Typeface; 34bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.text.Layout.Alignment; 35bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.text.StaticLayout; 36bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.text.TextPaint; 3732ce7f17a85abf9b175f773371308876f7401547Dianne Hackbornimport android.util.DisplayMetrics; 38bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onoratoimport android.util.Log; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Various utilities shared amongst the Launcher's classes. 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectfinal class Utilities { 461291a8c236c84451321438cb68855f6f2eb24959Joe Onorato private static final String TAG = "Launcher.Utilities"; 471291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 489392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato private static final boolean TEXT_BURN = false; 499392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconWidth = -1; 5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static int sIconHeight = -1; 526665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static int sIconTextureWidth = -1; 536665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static int sIconTextureHeight = -1; 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Paint sPaint = new Paint(); 561291a8c236c84451321438cb68855f6f2eb24959Joe Onorato private static final Paint sBlurPaint = new Paint(); 57eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato private static final Paint sGlowColorPressedPaint = new Paint(); 58c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato private static final Paint sGlowColorFocusedPaint = new Paint(); 591291a8c236c84451321438cb68855f6f2eb24959Joe Onorato private static final Paint sEmptyPaint = new Paint(); 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Rect sBounds = new Rect(); 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final Rect sOldBounds = new Rect(); 6289911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy private static final Canvas sCanvas = new Canvas(); 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static { 6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Paint.FILTER_BITMAP_FLAG)); 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) { 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapWidth = bitmap.getWidth(); 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int bitmapHeight = bitmap.getHeight(); 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (bitmapWidth < width || bitmapHeight < height) { 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int color = context.getResources().getColor(R.color.window_background); 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth, 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmapHeight < height ? height : bitmapHeight, Bitmap.Config.RGB_565); 7832ce7f17a85abf9b175f773371308876f7401547Dianne Hackborn centered.setDensity(bitmap.getDensity()); 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Canvas canvas = new Canvas(centered); 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawColor(color); 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(bitmap, (width - bitmapWidth) / 2.0f, (height - bitmapHeight) / 2.0f, 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project null); 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project bitmap = centered; 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return bitmap; 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns a Drawable representing the thumbnail of the specified Drawable. 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The size of the thumbnail is defined by the dimension 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * android.R.dimen.launcher_application_icon_size. 9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param icon The icon to get a thumbnail of. 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return A thumbnail for the specified icon or the icon itself if the 99fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams * thumbnail could not be created. 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1016665c0f1fec6ec0962896622986340081df992e7Joe Onorato static Drawable createIconThumbnail(Drawable icon, Context context) { 1029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (sCanvas) { // we share the statics :-( 1039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (sIconWidth == -1) { 1046665c0f1fec6ec0962896622986340081df992e7Joe Onorato initStatics(context); 105583ed3ba08644912ec0f3ec8ceb939f9eb0b8e86Mitsuru Oshima } 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int width = sIconWidth; 1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int height = sIconHeight; 1099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (icon instanceof PaintDrawable) { 1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PaintDrawable painter = (PaintDrawable) icon; 1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato painter.setIntrinsicWidth(width); 1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato painter.setIntrinsicHeight(height); 1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else if (icon instanceof BitmapDrawable) { 1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Ensure the bitmap has a density. 1169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Bitmap bitmap = bitmapDrawable.getBitmap(); 1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconWidth = icon.getIntrinsicWidth(); 1239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconHeight = icon.getIntrinsicHeight(); 1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 12589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (iconWidth > 0 && iconHeight > 0) { 12689911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (width < iconWidth || height < iconHeight) { 1279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final float ratio = (float) iconWidth / iconHeight; 1289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (iconWidth > iconHeight) { 1309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato height = (int) (width / ratio); 1319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else if (iconHeight > iconWidth) { 1329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato width = (int) (height * ratio); 1339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? 1369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; 1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 1389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Canvas canvas = sCanvas; 1399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato canvas.setBitmap(thumb); 1409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Copy the old bounds to restore them later 1419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we were to do oldBounds = icon.getBounds(), 1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // the call to setBounds() that follows would 1439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // change the same instance and we would lose the 1449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // old bounds 1459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato sOldBounds.set(icon.getBounds()); 1469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int x = (sIconWidth - width) / 2; 1479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int y = (sIconHeight - height) / 2; 1489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.setBounds(x, y, x + width, y + height); 1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.draw(canvas); 1509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.setBounds(sOldBounds); 1519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon = new FastBitmapDrawable(thumb); 1529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else if (iconWidth < width && iconHeight < height) { 1539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Bitmap.Config c = Bitmap.Config.ARGB_8888; 1549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Canvas canvas = sCanvas; 1569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato canvas.setBitmap(thumb); 1579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato sOldBounds.set(icon.getBounds()); 1589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int x = (width - iconWidth) / 2; 1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int y = (height - iconHeight) / 2; 1609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.setBounds(x, y, x + iconWidth, y + iconHeight); 1619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.draw(canvas); 1629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon.setBounds(sOldBounds); 1639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato icon = new FastBitmapDrawable(thumb); 1649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return icon; 1689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1716665c0f1fec6ec0962896622986340081df992e7Joe Onorato static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; 1726665c0f1fec6ec0962896622986340081df992e7Joe Onorato static int sColorIndex = 0; 1736665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1746665c0f1fec6ec0962896622986340081df992e7Joe Onorato /** 1756665c0f1fec6ec0962896622986340081df992e7Joe Onorato * Returns a bitmap suitable for the all apps view. The bitmap will be a power 1766665c0f1fec6ec0962896622986340081df992e7Joe Onorato * of two sized ARGB_8888 bitmap that can be used as a gl texture. 1776665c0f1fec6ec0962896622986340081df992e7Joe Onorato */ 1786665c0f1fec6ec0962896622986340081df992e7Joe Onorato static Bitmap createAllAppsBitmap(Drawable icon, Context context) { 1796665c0f1fec6ec0962896622986340081df992e7Joe Onorato synchronized (sCanvas) { // we share the statics :-( 1806665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sIconWidth == -1) { 1816665c0f1fec6ec0962896622986340081df992e7Joe Onorato initStatics(context); 1826665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1836665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1846665c0f1fec6ec0962896622986340081df992e7Joe Onorato int width = sIconWidth; 1856665c0f1fec6ec0962896622986340081df992e7Joe Onorato int height = sIconHeight; 1866665c0f1fec6ec0962896622986340081df992e7Joe Onorato 1876665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (icon instanceof PaintDrawable) { 1886665c0f1fec6ec0962896622986340081df992e7Joe Onorato PaintDrawable painter = (PaintDrawable) icon; 1896665c0f1fec6ec0962896622986340081df992e7Joe Onorato painter.setIntrinsicWidth(width); 1906665c0f1fec6ec0962896622986340081df992e7Joe Onorato painter.setIntrinsicHeight(height); 1916665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (icon instanceof BitmapDrawable) { 1926665c0f1fec6ec0962896622986340081df992e7Joe Onorato // Ensure the bitmap has a density. 1936665c0f1fec6ec0962896622986340081df992e7Joe Onorato BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 1946665c0f1fec6ec0962896622986340081df992e7Joe Onorato Bitmap bitmap = bitmapDrawable.getBitmap(); 1956665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 1966665c0f1fec6ec0962896622986340081df992e7Joe Onorato bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); 1976665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1986665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 1996665c0f1fec6ec0962896622986340081df992e7Joe Onorato int sourceWidth = icon.getIntrinsicWidth(); 2006665c0f1fec6ec0962896622986340081df992e7Joe Onorato int sourceHeight = icon.getIntrinsicHeight(); 2016665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2026665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sourceWidth > 0 && sourceWidth > 0) { 2036665c0f1fec6ec0962896622986340081df992e7Joe Onorato // There are intrinsic sizes. 20489911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (width < sourceWidth || height < sourceHeight) { 2056665c0f1fec6ec0962896622986340081df992e7Joe Onorato // It's too big, scale it down. 2066665c0f1fec6ec0962896622986340081df992e7Joe Onorato final float ratio = (float) sourceWidth / sourceHeight; 2076665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (sourceWidth > sourceHeight) { 2086665c0f1fec6ec0962896622986340081df992e7Joe Onorato height = (int) (width / ratio); 2096665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (sourceHeight > sourceWidth) { 2106665c0f1fec6ec0962896622986340081df992e7Joe Onorato width = (int) (height * ratio); 2116665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2126665c0f1fec6ec0962896622986340081df992e7Joe Onorato } else if (sourceWidth < width && sourceHeight < height) { 2136665c0f1fec6ec0962896622986340081df992e7Joe Onorato // It's small, use the size they gave us. 2146665c0f1fec6ec0962896622986340081df992e7Joe Onorato width = sourceWidth; 21589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy height = sourceHeight; 2166665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2176665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2186665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2196665c0f1fec6ec0962896622986340081df992e7Joe Onorato // no intrinsic size --> use default size 2206665c0f1fec6ec0962896622986340081df992e7Joe Onorato int textureWidth = sIconTextureWidth; 2216665c0f1fec6ec0962896622986340081df992e7Joe Onorato int textureHeight = sIconTextureHeight; 2226665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2236665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, 2246665c0f1fec6ec0962896622986340081df992e7Joe Onorato Bitmap.Config.ARGB_8888); 2256665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Canvas canvas = sCanvas; 2266665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.setBitmap(bitmap); 2276665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2286665c0f1fec6ec0962896622986340081df992e7Joe Onorato final int left = (textureWidth-width) / 2; 2296665c0f1fec6ec0962896622986340081df992e7Joe Onorato final int top = (textureHeight-height) / 2; 2306665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2316665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (false) { 2326665c0f1fec6ec0962896622986340081df992e7Joe Onorato // draw a big box for the icon for debugging 2336665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.drawColor(sColors[sColorIndex]); 2346665c0f1fec6ec0962896622986340081df992e7Joe Onorato if (++sColorIndex >= sColors.length) sColorIndex = 0; 2356665c0f1fec6ec0962896622986340081df992e7Joe Onorato Paint debugPaint = new Paint(); 2366665c0f1fec6ec0962896622986340081df992e7Joe Onorato debugPaint.setColor(0xffcccc00); 2376665c0f1fec6ec0962896622986340081df992e7Joe Onorato canvas.drawRect(left, top, left+width, top+height, debugPaint); 2386665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2396665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2406665c0f1fec6ec0962896622986340081df992e7Joe Onorato sOldBounds.set(icon.getBounds()); 2416665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.setBounds(left, top, left+width, top+height); 2426665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.draw(canvas); 2436665c0f1fec6ec0962896622986340081df992e7Joe Onorato icon.setBounds(sOldBounds); 2446665c0f1fec6ec0962896622986340081df992e7Joe Onorato 2456665c0f1fec6ec0962896622986340081df992e7Joe Onorato return bitmap; 2466665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2476665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 2486665c0f1fec6ec0962896622986340081df992e7Joe Onorato 249c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato static void drawSelectedAllAppsBitmap(Canvas dest, int destWidth, int destHeight, 250eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato boolean pressed, Bitmap src) { 2511291a8c236c84451321438cb68855f6f2eb24959Joe Onorato synchronized (sCanvas) { // we share the statics :-( 2521291a8c236c84451321438cb68855f6f2eb24959Joe Onorato if (sIconWidth == -1) { 2531291a8c236c84451321438cb68855f6f2eb24959Joe Onorato // We can't have gotten to here without src being initialized, which 2541291a8c236c84451321438cb68855f6f2eb24959Joe Onorato // comes from this file already. So just assert. 2551291a8c236c84451321438cb68855f6f2eb24959Joe Onorato //initStatics(context); 2561291a8c236c84451321438cb68855f6f2eb24959Joe Onorato throw new RuntimeException("Assertion failed: Utilities not initialized"); 2571291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 2581291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 2591291a8c236c84451321438cb68855f6f2eb24959Joe Onorato dest.drawColor(0, PorterDuff.Mode.CLEAR); 260cdd117935f51d66f6f212387300d851f81aa071fMike Reed 2611291a8c236c84451321438cb68855f6f2eb24959Joe Onorato int[] xy = new int[2]; 262cdd117935f51d66f6f212387300d851f81aa071fMike Reed Bitmap mask = src.extractAlpha(sBlurPaint, xy); 2631291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 264cdd117935f51d66f6f212387300d851f81aa071fMike Reed float px = (destWidth - src.getWidth()) / 2; 265cdd117935f51d66f6f212387300d851f81aa071fMike Reed float py = (destHeight - src.getHeight()) / 2; 266c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato dest.drawBitmap(mask, px + xy[0], py + xy[1], 267eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato pressed ? sGlowColorPressedPaint : sGlowColorFocusedPaint); 2681291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 2691291a8c236c84451321438cb68855f6f2eb24959Joe Onorato mask.recycle(); 2701291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 2711291a8c236c84451321438cb68855f6f2eb24959Joe Onorato } 2726665c0f1fec6ec0962896622986340081df992e7Joe Onorato 27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns a Bitmap representing the thumbnail of the specified Bitmap. 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The size of the thumbnail is defined by the dimension 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * android.R.dimen.launcher_application_icon_size. 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param bitmap The bitmap to get a thumbnail of. 27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return A thumbnail for the specified bitmap or the bitmap itself if the 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * thumbnail could not be created. 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context) { 2859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (sCanvas) { // we share the statics :-( 2869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (sIconWidth == -1) { 2876665c0f1fec6ec0962896622986340081df992e7Joe Onorato initStatics(context); 2889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int width = sIconWidth; 2919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int height = sIconHeight; 29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int bitmapWidth = bitmap.getWidth(); 2949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int bitmapHeight = bitmap.getHeight(); 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29689911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (width > 0 && height > 0) { 29789911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (width < bitmapWidth || height < bitmapHeight) { 29889911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final float ratio = (float) bitmapWidth / bitmapHeight; 29989911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy 30089911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy if (bitmapWidth > bitmapHeight) { 30189911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy height = (int) (width / ratio); 30289911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy } else if (bitmapHeight > bitmapWidth) { 30389911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy width = (int) (height * ratio); 30489911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy } 30589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy 30689911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Bitmap.Config c = (width == sIconWidth && height == sIconHeight) ? 30789911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy bitmap.getConfig() : Bitmap.Config.ARGB_8888; 30889911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 30989911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Canvas canvas = sCanvas; 31089911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Paint paint = sPaint; 31189911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy canvas.setBitmap(thumb); 31289911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy paint.setDither(false); 31389911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy paint.setFilterBitmap(true); 31489911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy sBounds.set((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height); 31589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy sOldBounds.set(0, 0, bitmapWidth, bitmapHeight); 31689911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy canvas.drawBitmap(bitmap, sOldBounds, sBounds, paint); 31789911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy return thumb; 31889911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy } else if (bitmapWidth < width || bitmapHeight < height) { 31989911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Bitmap.Config c = Bitmap.Config.ARGB_8888; 32089911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c); 32189911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Canvas canvas = sCanvas; 32289911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy final Paint paint = sPaint; 32389911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy canvas.setBitmap(thumb); 32489911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy paint.setDither(false); 32589911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy paint.setFilterBitmap(true); 32689911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy canvas.drawBitmap(bitmap, (sIconWidth - bitmapWidth) / 2, 32789911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy (sIconHeight - bitmapHeight) / 2, paint); 32889911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy return thumb; 3299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return bitmap; 33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 335bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 3366665c0f1fec6ec0962896622986340081df992e7Joe Onorato private static void initStatics(Context context) { 3376665c0f1fec6ec0962896622986340081df992e7Joe Onorato final Resources resources = context.getResources(); 3381291a8c236c84451321438cb68855f6f2eb24959Joe Onorato final DisplayMetrics metrics = resources.getDisplayMetrics(); 3391291a8c236c84451321438cb68855f6f2eb24959Joe Onorato final float density = metrics.density; 3401291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 3416665c0f1fec6ec0962896622986340081df992e7Joe Onorato sIconWidth = sIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); 3426665c0f1fec6ec0962896622986340081df992e7Joe Onorato sIconTextureWidth = sIconTextureHeight = roundToPow2(sIconWidth); 3431291a8c236c84451321438cb68855f6f2eb24959Joe Onorato 344a4c0cb965575b7a0832d92bc0b33e06c7c66cb10Joe Onorato sBlurPaint.setMaskFilter(new BlurMaskFilter(5 * density, BlurMaskFilter.Blur.NORMAL)); 345eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato sGlowColorPressedPaint.setColor(0xffffc300); 346eb8325a9e24cda47720152e1e95f5d86ab11f200Joe Onorato sGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 347c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato sGlowColorFocusedPaint.setColor(0xffff8e00); 348c61cff9299a54599c2b214de7c819b6be0412f4eJoe Onorato sGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 3496665c0f1fec6ec0962896622986340081df992e7Joe Onorato } 3506665c0f1fec6ec0962896622986340081df992e7Joe Onorato 351bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato static class BubbleText { 352bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private static final int MAX_LINES = 2; 353bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private TextPaint mTextPaint; 354bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 355bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private float mBubblePadding; 356bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private RectF mBubbleRect = new RectF(); 357bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 358bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private float mTextWidth; 359bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private int mLeading; 360bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private int mFirstLineY; 361bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private int mLineHeight; 362bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 363bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private int mBitmapWidth; 364bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato private int mBitmapHeight; 365bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 366bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato BubbleText(Context context) { 367bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final Resources resources = context.getResources(); 368bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 369bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final float scale = resources.getDisplayMetrics().density; 370bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 371bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final float paddingLeft = 5.0f * scale; 372bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final float paddingRight = 5.0f * scale; 373bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final float cellWidth = resources.getDimension(R.dimen.workspace_cell_width); 374bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato final float bubbleWidth = cellWidth - paddingLeft - paddingRight; 37543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato mBubblePadding = 3.0f * scale; 376bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 377bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato RectF bubbleRect = mBubbleRect; 378bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato bubbleRect.left = 0; 379bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato bubbleRect.top = 0; 380bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato bubbleRect.right = (int)(bubbleWidth+0.5f); 381bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 382bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mTextWidth = bubbleWidth - mBubblePadding - mBubblePadding; 383bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 38489911d2450f5db92d79e3bcefa9d324e9e8c4900Romain Guy Paint rectPaint = new Paint(); 385efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato rectPaint.setColor(0xff000000); 38643e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato rectPaint.setAntiAlias(true); 387bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 388bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato TextPaint textPaint = mTextPaint = new TextPaint(); 389efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato textPaint.setTypeface(Typeface.DEFAULT); 390efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato textPaint.setTextSize(13*scale); 391bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato textPaint.setColor(0xffffffff); 39243e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato textPaint.setAntiAlias(true); 3939392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato if (TEXT_BURN) { 3949392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato textPaint.setShadowLayer(8, 0, 0, 0xff000000); 3959392a75d0493fc9aacbb1e6e63518b0fa66cc3b9Joe Onorato } 396bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 397bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato float ascent = -textPaint.ascent(); 398bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato float descent = textPaint.descent(); 39943e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato float leading = 0.0f;//(ascent+descent) * 0.1f; 400bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mLeading = (int)(leading + 0.5f); 401bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mFirstLineY = (int)(leading + ascent + 0.5f); 402bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mLineHeight = (int)(leading + ascent + descent + 0.5f); 403bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 404bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mBitmapWidth = roundToPow2((int)(mBubbleRect.width() + 0.5f)); 40543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato mBitmapHeight = roundToPow2((int)((MAX_LINES * mLineHeight) + leading + 0.5f)); 406bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 407fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato mBubbleRect.offsetTo((mBitmapWidth-mBubbleRect.width())/2, 0); 408fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato 409080d9b614e609826dce2606f9e474af674ead933Joe Onorato if (false) { 410080d9b614e609826dce2606f9e474af674ead933Joe Onorato Log.d(TAG, "mBitmapWidth=" + mBitmapWidth + " mBitmapHeight=" 411080d9b614e609826dce2606f9e474af674ead933Joe Onorato + mBitmapHeight + " w=" + ((int)(mBubbleRect.width() + 0.5f)) 412080d9b614e609826dce2606f9e474af674ead933Joe Onorato + " h=" + ((int)((MAX_LINES * mLineHeight) + leading + 0.5f))); 413080d9b614e609826dce2606f9e474af674ead933Joe Onorato } 414bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 415bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 416bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato /** You own the bitmap after this and you must call recycle on it. */ 417bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Bitmap createTextBitmap(String text) { 418bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Bitmap b = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888); 419bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Canvas c = new Canvas(b); 420bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 421bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato StaticLayout layout = new StaticLayout(text, mTextPaint, (int)mTextWidth, 422bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato Alignment.ALIGN_CENTER, 1, 0, true); 423bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int lineCount = layout.getLineCount(); 424bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato if (lineCount > MAX_LINES) { 425bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato lineCount = MAX_LINES; 426bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 427fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //if (!TEXT_BURN && lineCount > 0) { 428fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //RectF bubbleRect = mBubbleRect; 429fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //bubbleRect.bottom = height(lineCount); 430fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint); 431fd22dac33e535779d1006fcfe22ef2b95152d916Jason Sams //} 432bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato for (int i=0; i<lineCount; i++) { 433fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato //int x = (int)((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f); 434fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato //int y = mFirstLineY + (i * mLineHeight); 435fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato int x = (int)(mBubbleRect.left 436fccc8dfc8a442b8d5ea415e1cba7ffde349319d9Joe Onorato + ((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f)); 437bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int y = mFirstLineY + (i * mLineHeight); 438bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato c.drawText(text.substring(layout.getLineStart(i), layout.getLineEnd(i)), 439bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato x, y, mTextPaint); 440bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 441bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 442bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato return b; 443bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 44443e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 44543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato private int height(int lineCount) { 44643e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return (int)((lineCount * mLineHeight) + mLeading + mLeading + 0.0f); 44743e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 44843e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 44943e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBubbleWidth() { 45043e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return (int)(mBubbleRect.width() + 0.5f); 45143e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 45243e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 45343e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getMaxBubbleHeight() { 45443e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return height(MAX_LINES); 45543e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 45643e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 45743e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBitmapWidth() { 45843e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return mBitmapWidth; 45943e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 46043e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato 46143e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato int getBitmapHeight() { 46243e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato return mBitmapHeight; 46343e7bcf0ad7b487df9244bc5491695b130d331c7Joe Onorato } 464bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 465bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato 466bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato /** Only works for positive numbers. */ 467bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato static int roundToPow2(int n) { 468bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int orig = n; 469bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n >>= 1; 470bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato int mask = 0x8000000; 471bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato while (mask != 0 && (n & mask) == 0) { 472bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mask >>= 1; 473bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 474bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato while (mask != 0) { 475bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n |= mask; 476bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato mask >>= 1; 477bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 478bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n += 1; 479bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato if (n != orig) { 480bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato n <<= 1; 481bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 482bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato return n; 483bf15cb44cc8e5ea9a19ab8aaee8e02c96bd6130cJoe Onorato } 48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 485