Loading src/com/android/launcher3/IconCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -780,7 +780,7 @@ public class IconCache { } private static final class IconDB extends SQLiteCacheHelper { private final static int RELEASE_VERSION = 21; private final static int RELEASE_VERSION = 22; private final static String TABLE_NAME = "icons"; private final static String COLUMN_ROWID = "rowid"; Loading src/com/android/launcher3/graphics/IconNormalizer.java +25 −29 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; Loading Loading @@ -66,12 +67,10 @@ public class IconNormalizer { private final int mMaxSize; private final Bitmap mBitmap; private final Bitmap mBitmapARGB; private final Canvas mCanvas; private final Paint mPaintMaskShape; private final Paint mPaintMaskShapeOutline; private final byte[] mPixels; private final int[] mPixelsARGB; private final Rect mAdaptiveIconBounds; private float mAdaptiveIconScale; Loading @@ -83,9 +82,6 @@ public class IconNormalizer { private final Path mShapePath; private final Matrix mMatrix; private final Paint mPaintIcon; private final Canvas mCanvasARGB; /** package private **/ IconNormalizer(Context context) { // Use twice the icon size as maximum size to avoid scaling down twice. Loading @@ -93,19 +89,11 @@ public class IconNormalizer { mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); mCanvas = new Canvas(mBitmap); mPixels = new byte[mMaxSize * mMaxSize]; mPixelsARGB = new int[mMaxSize * mMaxSize]; mLeftBorder = new float[mMaxSize]; mRightBorder = new float[mMaxSize]; mBounds = new Rect(); mAdaptiveIconBounds = new Rect(); // Needed for isShape() method mBitmapARGB = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ARGB_8888); mCanvasARGB = new Canvas(mBitmapARGB); mPaintIcon = new Paint(); mPaintIcon.setColor(Color.WHITE); mPaintMaskShape = new Paint(); mPaintMaskShape.setColor(Color.RED); mPaintMaskShape.setStyle(Paint.Style.FILL); Loading @@ -115,7 +103,7 @@ public class IconNormalizer { mPaintMaskShapeOutline.setStrokeWidth(2 * context.getResources().getDisplayMetrics().density); mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); mPaintMaskShapeOutline.setColor(Color.BLACK); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mShapePath = new Path(); mMatrix = new Matrix(); Loading @@ -141,8 +129,6 @@ public class IconNormalizer { // Condition 2: // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation // should generate transparent image, if the actual icon is equivalent to the shape. mBitmapARGB.eraseColor(Color.TRANSPARENT); mCanvasARGB.drawBitmap(mBitmap, 0, 0, mPaintIcon); // Fit the shape within the icon's bounding box mMatrix.reset(); Loading @@ -151,31 +137,41 @@ public class IconNormalizer { maskPath.transform(mMatrix, mShapePath); // XOR operation mCanvasARGB.drawPath(mShapePath, mPaintMaskShape); mCanvas.drawPath(mShapePath, mPaintMaskShape); // DST_OUT operation around the mask path outline mCanvasARGB.drawPath(mShapePath, mPaintMaskShapeOutline); mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline); // Check if the result is almost transparent return isTransparentBitmap(mBitmapARGB); return isTransparentBitmap(); } /** * Used to determine if certain the bitmap is transparent. */ private boolean isTransparentBitmap(Bitmap bitmap) { int w = mBounds.width(); int h = mBounds.height(); bitmap.getPixels(mPixelsARGB, 0 /* the first index to write into the array */, w /* stride */, mBounds.left, mBounds.top, w, h); private boolean isTransparentBitmap() { ByteBuffer buffer = ByteBuffer.wrap(mPixels); buffer.rewind(); mBitmap.copyPixelsToBuffer(buffer); int y = mBounds.top; // buffer position int index = y * mMaxSize; // buffer shift after every row, width of buffer = mMaxSize int rowSizeDiff = mMaxSize - mBounds.right; int sum = 0; for (int i = w * h - 1; i >= 0; i--) { if(Color.alpha(mPixelsARGB[i]) > MIN_VISIBLE_ALPHA) { for (; y < mBounds.bottom; y++) { index += mBounds.left; for (int x = mBounds.left; x < mBounds.right; x++) { if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { sum++; } index++; } index += rowSizeDiff; } float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; } Loading Loading @@ -306,7 +302,7 @@ public class IconNormalizer { mBounds.bottom = bottomY; if (outBounds != null) { outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top), outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height, 1 - ((float) mBounds.right) / width, 1 - ((float) mBounds.bottom) / height); } Loading Loading
src/com/android/launcher3/IconCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -780,7 +780,7 @@ public class IconCache { } private static final class IconDB extends SQLiteCacheHelper { private final static int RELEASE_VERSION = 21; private final static int RELEASE_VERSION = 22; private final static String TABLE_NAME = "icons"; private final static String COLUMN_ROWID = "rowid"; Loading
src/com/android/launcher3/graphics/IconNormalizer.java +25 −29 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; Loading Loading @@ -66,12 +67,10 @@ public class IconNormalizer { private final int mMaxSize; private final Bitmap mBitmap; private final Bitmap mBitmapARGB; private final Canvas mCanvas; private final Paint mPaintMaskShape; private final Paint mPaintMaskShapeOutline; private final byte[] mPixels; private final int[] mPixelsARGB; private final Rect mAdaptiveIconBounds; private float mAdaptiveIconScale; Loading @@ -83,9 +82,6 @@ public class IconNormalizer { private final Path mShapePath; private final Matrix mMatrix; private final Paint mPaintIcon; private final Canvas mCanvasARGB; /** package private **/ IconNormalizer(Context context) { // Use twice the icon size as maximum size to avoid scaling down twice. Loading @@ -93,19 +89,11 @@ public class IconNormalizer { mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); mCanvas = new Canvas(mBitmap); mPixels = new byte[mMaxSize * mMaxSize]; mPixelsARGB = new int[mMaxSize * mMaxSize]; mLeftBorder = new float[mMaxSize]; mRightBorder = new float[mMaxSize]; mBounds = new Rect(); mAdaptiveIconBounds = new Rect(); // Needed for isShape() method mBitmapARGB = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ARGB_8888); mCanvasARGB = new Canvas(mBitmapARGB); mPaintIcon = new Paint(); mPaintIcon.setColor(Color.WHITE); mPaintMaskShape = new Paint(); mPaintMaskShape.setColor(Color.RED); mPaintMaskShape.setStyle(Paint.Style.FILL); Loading @@ -115,7 +103,7 @@ public class IconNormalizer { mPaintMaskShapeOutline.setStrokeWidth(2 * context.getResources().getDisplayMetrics().density); mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); mPaintMaskShapeOutline.setColor(Color.BLACK); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mShapePath = new Path(); mMatrix = new Matrix(); Loading @@ -141,8 +129,6 @@ public class IconNormalizer { // Condition 2: // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation // should generate transparent image, if the actual icon is equivalent to the shape. mBitmapARGB.eraseColor(Color.TRANSPARENT); mCanvasARGB.drawBitmap(mBitmap, 0, 0, mPaintIcon); // Fit the shape within the icon's bounding box mMatrix.reset(); Loading @@ -151,31 +137,41 @@ public class IconNormalizer { maskPath.transform(mMatrix, mShapePath); // XOR operation mCanvasARGB.drawPath(mShapePath, mPaintMaskShape); mCanvas.drawPath(mShapePath, mPaintMaskShape); // DST_OUT operation around the mask path outline mCanvasARGB.drawPath(mShapePath, mPaintMaskShapeOutline); mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline); // Check if the result is almost transparent return isTransparentBitmap(mBitmapARGB); return isTransparentBitmap(); } /** * Used to determine if certain the bitmap is transparent. */ private boolean isTransparentBitmap(Bitmap bitmap) { int w = mBounds.width(); int h = mBounds.height(); bitmap.getPixels(mPixelsARGB, 0 /* the first index to write into the array */, w /* stride */, mBounds.left, mBounds.top, w, h); private boolean isTransparentBitmap() { ByteBuffer buffer = ByteBuffer.wrap(mPixels); buffer.rewind(); mBitmap.copyPixelsToBuffer(buffer); int y = mBounds.top; // buffer position int index = y * mMaxSize; // buffer shift after every row, width of buffer = mMaxSize int rowSizeDiff = mMaxSize - mBounds.right; int sum = 0; for (int i = w * h - 1; i >= 0; i--) { if(Color.alpha(mPixelsARGB[i]) > MIN_VISIBLE_ALPHA) { for (; y < mBounds.bottom; y++) { index += mBounds.left; for (int x = mBounds.left; x < mBounds.right; x++) { if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { sum++; } index++; } index += rowSizeDiff; } float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; } Loading Loading @@ -306,7 +302,7 @@ public class IconNormalizer { mBounds.bottom = bottomY; if (outBounds != null) { outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top), outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height, 1 - ((float) mBounds.right) / width, 1 - ((float) mBounds.bottom) / height); } Loading