From 5bb50bdb13f5fc22f5febd9480e78222b26c6fe7 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Fri, 3 Dec 2010 11:39:55 -0800 Subject: [PATCH] Improving the look of holographic outlines - The outlines are used in AllApps, Workspace and Customize Change-Id: I1c3aba81df163c98a839498a3d421a8f03c51f06 --- .../launcher2/HolographicOutlineHelper.java | 76 +++++++++---------- src/com/android/launcher2/PagedViewIcon.java | 4 +- .../android/launcher2/PagedViewWidget.java | 2 +- src/com/android/launcher2/Workspace.java | 6 +- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java index 658490accc..bf4c05ac3c 100644 --- a/src/com/android/launcher2/HolographicOutlineHelper.java +++ b/src/com/android/launcher2/HolographicOutlineHelper.java @@ -29,6 +29,7 @@ public class HolographicOutlineHelper { private final Paint mHolographicPaint = new Paint(); private final Paint mBlurPaint = new Paint(); private final Paint mErasePaint = new Paint(); + private final Paint mAlphaClipPaint = new Paint(); public static final int OUTER_BLUR_RADIUS; @@ -36,6 +37,10 @@ public class HolographicOutlineHelper { private static final BlurMaskFilter sMediumOuterBlurMaskFilter; private static final BlurMaskFilter sThinOuterBlurMaskFilter; private static final BlurMaskFilter sThickInnerBlurMaskFilter; + private static final BlurMaskFilter sMediumInnerBlurMaskFilter; + + private static final int THICK = 0; + private static final int MEDIUM = 1; static { final float scale = LauncherApplication.getScreenDensity(); @@ -47,6 +52,7 @@ public class HolographicOutlineHelper { sMediumOuterBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.OUTER); sThinOuterBlurMaskFilter = new BlurMaskFilter(scale * 1.0f, BlurMaskFilter.Blur.OUTER); sThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL); + sMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL); } private static final MaskFilter sFineClipTable = TableMaskFilter.CreateClipTable(0, 20); @@ -62,6 +68,8 @@ public class HolographicOutlineHelper { mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mErasePaint.setFilterBitmap(true); mErasePaint.setAntiAlias(true); + MaskFilter alphaClipTable = TableMaskFilter.CreateClipTable(180, 255); + mAlphaClipPaint.setMaskFilter(alphaClipTable); } /** @@ -98,66 +106,42 @@ public class HolographicOutlineHelper { mHolographicPaint.setMaskFilter(sCoarseClipTable); mHolographicPaint.setAlpha(150); mHolographicPaint.setColor(color); + canvas.drawBitmap(glow, mTempOffset[0], mTempOffset[1], mHolographicPaint); glow.recycle(); } - /** - * Draws a solid outline around a bitmap, erasing the original pixels. - * - * @param bitmap The bitmap to modify - * @param canvas A canvas on the bitmap - * @param color The color to draw the outline and glow in - * @param removeOrig If true, punch out the original pixels to just leave the outline - */ - void applyExpensiveOuterOutline(Bitmap bitmap, Canvas canvas, int color, boolean removeOrig) { - Bitmap originalImage = null; - if (removeOrig) { - originalImage = bitmap.extractAlpha(); - } - - // Compute an outer blur on the original bitmap - mBlurPaint.setMaskFilter(sMediumOuterBlurMaskFilter); - Bitmap outline = bitmap.extractAlpha(mBlurPaint, mTempOffset); - - // Paint the blurred bitmap back into the canvas. Using the clip table causes any alpha - // pixels above a certain threshold to be rounded up to be fully opaque. This gives the - // effect of a thick outline, with a slight blur on the edge - mHolographicPaint.setColor(color); - mHolographicPaint.setMaskFilter(sFineClipTable); - canvas.drawBitmap(outline, mTempOffset[0], mTempOffset[1], mHolographicPaint); - outline.recycle(); - - if (removeOrig) { - // Finally, punch out the original pixels, leaving just the outline - canvas.drawBitmap(originalImage, 0, 0, mErasePaint); - originalImage.recycle(); - } - } - /** * Applies a more expensive and accurate outline to whatever is currently drawn in a specified * bitmap. */ void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, - int outlineColor) { + int outlineColor, int thickness) { + + // We start by removing most of the alpha channel so as to ignore shadows, and + // other types of partial transparency when defining the shape of the object + Bitmap glowShape = srcDst.extractAlpha(mAlphaClipPaint, mTempOffset); + // calculate the outer blur first - mBlurPaint.setMaskFilter(sThickOuterBlurMaskFilter); + mBlurPaint.setMaskFilter(thickness == THICK ? sThickOuterBlurMaskFilter : + sMediumOuterBlurMaskFilter); int[] outerBlurOffset = new int[2]; - Bitmap thickOuterBlur = srcDst.extractAlpha(mBlurPaint, outerBlurOffset); + Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset); mBlurPaint.setMaskFilter(sThinOuterBlurMaskFilter); int[] thinOuterBlurOffset = new int[2]; - Bitmap thinOuterBlur = srcDst.extractAlpha(mBlurPaint, thinOuterBlurOffset); + Bitmap thinOuterBlur = glowShape.extractAlpha(mBlurPaint, thinOuterBlurOffset); // calculate the inner blur + srcDstCanvas.setBitmap(glowShape); srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT); - mBlurPaint.setMaskFilter(sThickInnerBlurMaskFilter); + mBlurPaint.setMaskFilter(thickness == THICK ? sThickInnerBlurMaskFilter : + sMediumInnerBlurMaskFilter); int[] thickInnerBlurOffset = new int[2]; - Bitmap thickInnerBlur = srcDst.extractAlpha(mBlurPaint, thickInnerBlurOffset); + Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset); // mask out the inner blur srcDstCanvas.setBitmap(thickInnerBlur); - srcDstCanvas.drawBitmap(srcDst, -thickInnerBlurOffset[0], + srcDstCanvas.drawBitmap(glowShape, -thickInnerBlurOffset[0], -thickInnerBlurOffset[1], mErasePaint); srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(), mErasePaint); @@ -182,5 +166,17 @@ public class HolographicOutlineHelper { thinOuterBlur.recycle(); thickOuterBlur.recycle(); thickInnerBlur.recycle(); + glowShape.recycle(); } + + void applyThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, + int outlineColor) { + applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, THICK); + } + + void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, + int outlineColor) { + applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, MEDIUM); + } + } diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java index 0e72598e9f..300bab5f00 100644 --- a/src/com/android/launcher2/PagedViewIcon.java +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -81,7 +81,7 @@ public class PagedViewIcon extends CacheableTextView implements Checkable { Canvas holographicOutlineCanvas = new Canvas(holographicOutline); holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint); - sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(holographicOutline, + sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline, holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor); mHandler.post(new Runnable() { @@ -235,7 +235,7 @@ public class PagedViewIcon extends CacheableTextView implements Checkable { mPaint.setAlpha(255); checkedOutlineCanvas.drawBitmap(mIcon, 0, 0, mPaint); - sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline, + sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(mCheckedOutline, checkedOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor); } else { invalidateCheckedImage(); diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java index 40e507bb3d..4d4ccc2d44 100644 --- a/src/com/android/launcher2/PagedViewWidget.java +++ b/src/com/android/launcher2/PagedViewWidget.java @@ -80,7 +80,7 @@ public class PagedViewWidget extends LinearLayout { widget.mPreview.setAlpha(prevAlpha); widget.mHolographicOutlineCanvas.restore(); - sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(outline, + sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(outline, widget.mHolographicOutlineCanvas, widget.mHoloBlurColor, widget.mHoloOutlineColor); diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 7027d83593..42dbc9a1e5 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -1324,8 +1324,7 @@ public class Workspace extends SmoothPagedView canvas.setBitmap(b); drawDragView(v, canvas, padding); - mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true); - + mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor); return b; } @@ -1347,8 +1346,7 @@ public class Workspace extends SmoothPagedView canvas.setBitmap(b); canvas.drawRoundRect(new RectF(inset, inset, iconWidth - inset, iconHeight - inset), rectRadius, rectRadius, mExternalDragOutlinePaint); - mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true); - + mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor); return b; }