Improving the look of holographic outlines

- The outlines are used in AllApps, Workspace and Customize

Change-Id: I1c3aba81df163c98a839498a3d421a8f03c51f06
This commit is contained in:
Adam Cohen
2010-12-03 15:46:56 -08:00
parent 4b67b44244
commit 5bb50bdb13
4 changed files with 41 additions and 47 deletions
@@ -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);
}
}
+2 -2
View File
@@ -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();
@@ -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);
+2 -4
View File
@@ -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;
}