Improving the look of holographic outlines
- The outlines are used in AllApps, Workspace and Customize
Change-Id: I1c3aba81df163c98a839498a3d421a8f03c51f06
diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java
index 658490a..bf4c05a 100644
--- a/src/com/android/launcher2/HolographicOutlineHelper.java
+++ b/src/com/android/launcher2/HolographicOutlineHelper.java
@@ -29,6 +29,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 0e72598..300bab5 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -81,7 +81,7 @@
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 @@
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 40e507b..4d4ccc2 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -80,7 +80,7 @@
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 7027d83..42dbc9a 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1324,8 +1324,7 @@
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 @@
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;
}