15f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka/* 25f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Copyright (C) 2008 The Android Open Source Project 35f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * 45f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 55f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * you may not use this file except in compliance with the License. 65f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * You may obtain a copy of the License at 75f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * 85f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * http://www.apache.org/licenses/LICENSE-2.0 95f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * 105f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Unless required by applicable law or agreed to in writing, software 115f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 125f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * See the License for the specific language governing permissions and 145f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * limitations under the License. 155f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka */ 165f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 175f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkapackage com.android.launcher2; 185f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 195f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.Bitmap; 205f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.BlurMaskFilter; 215f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.Canvas; 225f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.Paint; 235f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.PorterDuff; 245f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkaimport android.graphics.PorterDuffXfermode; 255f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 265f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurkapublic class HolographicOutlineHelper { 275f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka private final Paint mHolographicPaint = new Paint(); 284be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private final Paint mBlurPaint = new Paint(); 295f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka private final Paint mErasePaint = new Paint(); 305f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 3138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka public static final int MAX_OUTER_BLUR_RADIUS; 321908d07151e0d3f82899f368874e41ed1e49ba16Winson Chung public static final int MIN_OUTER_BLUR_RADIUS; 334be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 3438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka private static final BlurMaskFilter sExtraThickOuterBlurMaskFilter; 358e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private static final BlurMaskFilter sThickOuterBlurMaskFilter; 368e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private static final BlurMaskFilter sMediumOuterBlurMaskFilter; 378e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private static final BlurMaskFilter sThinOuterBlurMaskFilter; 388e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private static final BlurMaskFilter sThickInnerBlurMaskFilter; 3938b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka private static final BlurMaskFilter sExtraThickInnerBlurMaskFilter; 405bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen private static final BlurMaskFilter sMediumInnerBlurMaskFilter; 415bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 425bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen private static final int THICK = 0; 435bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen private static final int MEDIUM = 1; 4438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka private static final int EXTRA_THICK = 2; 458e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 468e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy static { 478e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy final float scale = LauncherApplication.getScreenDensity(); 488e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 491908d07151e0d3f82899f368874e41ed1e49ba16Winson Chung MIN_OUTER_BLUR_RADIUS = (int) (scale * 1.0f); 5038b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka MAX_OUTER_BLUR_RADIUS = (int) (scale * 12.0f); 518e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 5238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka sExtraThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 12.0f, BlurMaskFilter.Blur.OUTER); 5338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka sThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.OUTER); 548e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy sMediumOuterBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.OUTER); 558e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy sThinOuterBlurMaskFilter = new BlurMaskFilter(scale * 1.0f, BlurMaskFilter.Blur.OUTER); 5638b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka sExtraThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.NORMAL); 578e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy sThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL); 585bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen sMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL); 598e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy } 604be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 6164a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung HolographicOutlineHelper() { 625f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mHolographicPaint.setFilterBitmap(true); 635f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mHolographicPaint.setAntiAlias(true); 644be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mBlurPaint.setFilterBitmap(true); 654be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mBlurPaint.setAntiAlias(true); 665f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); 675f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mErasePaint.setFilterBitmap(true); 685f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mErasePaint.setAntiAlias(true); 695f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 705f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 715f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka /** 725f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Returns the interpolated holographic highlight alpha for the effect we want when scrolling 735f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * pages. 745f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka */ 75b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung public static float highlightAlphaInterpolator(float r) { 76b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung float maxAlpha = 0.6f; 77e8878e3c5ac2b426be931018493ce82bd9c90378Winson Chung return (float) Math.pow(maxAlpha * (1.0f - r), 1.5f); 785f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 795f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 805f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka /** 815f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Returns the interpolated view alpha for the effect we want when scrolling pages. 825f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka */ 83b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung public static float viewAlphaInterpolator(float r) { 84e8878e3c5ac2b426be931018493ce82bd9c90378Winson Chung final float pivot = 0.95f; 855f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka if (r < pivot) { 86e8878e3c5ac2b426be931018493ce82bd9c90378Winson Chung return (float) Math.pow(r / pivot, 1.5f); 875f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } else { 885f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return 1.0f; 895f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 905f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 915f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 928e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy /** 9364a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung * Applies a more expensive and accurate outline to whatever is currently drawn in a specified 9464a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung * bitmap. 955f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka */ 9664a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 975bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen int outlineColor, int thickness) { 988c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, true, 998db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng thickness); 1008db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng } 1018db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 1028c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka int outlineColor, boolean clipAlpha, int thickness) { 1035bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 1045bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen // We start by removing most of the alpha channel so as to ignore shadows, and 1055bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen // other types of partial transparency when defining the shape of the object 1068c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka if (clipAlpha) { 1078c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka int[] srcBuffer = new int[srcDst.getWidth() * srcDst.getHeight()]; 1088c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka srcDst.getPixels(srcBuffer, 1098c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka 0, srcDst.getWidth(), 0, 0, srcDst.getWidth(), srcDst.getHeight()); 1108c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka for (int i = 0; i < srcBuffer.length; i++) { 1118c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka final int alpha = srcBuffer[i] >>> 24; 1128c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka if (alpha < 188) { 1138c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka srcBuffer[i] = 0; 1148c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka } 1158c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka } 1168c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka srcDst.setPixels(srcBuffer, 1178c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka 0, srcDst.getWidth(), 0, 0, srcDst.getWidth(), srcDst.getHeight()); 1188db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng } 1198c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka Bitmap glowShape = srcDst.extractAlpha(); 1205bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 12164a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // calculate the outer blur first 12238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka BlurMaskFilter outerBlurMaskFilter; 12338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka switch (thickness) { 12438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case EXTRA_THICK: 12538b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka outerBlurMaskFilter = sExtraThickOuterBlurMaskFilter; 12638b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 12738b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case THICK: 12838b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka outerBlurMaskFilter = sThickOuterBlurMaskFilter; 12938b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 13038b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case MEDIUM: 13138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka outerBlurMaskFilter = sMediumOuterBlurMaskFilter; 13238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 13338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka default: 13438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka throw new RuntimeException("Invalid blur thickness"); 13538b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka } 13638b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka mBlurPaint.setMaskFilter(outerBlurMaskFilter); 13764a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung int[] outerBlurOffset = new int[2]; 1385bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset); 13938b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka if (thickness == EXTRA_THICK) { 14038b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka mBlurPaint.setMaskFilter(sMediumOuterBlurMaskFilter); 14138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka } else { 14238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka mBlurPaint.setMaskFilter(sThinOuterBlurMaskFilter); 14338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka } 14438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka 14538b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka int[] brightOutlineOffset = new int[2]; 14638b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka Bitmap brightOutline = glowShape.extractAlpha(mBlurPaint, brightOutlineOffset); 1475f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 14864a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // calculate the inner blur 1495bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen srcDstCanvas.setBitmap(glowShape); 15064a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT); 15138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka BlurMaskFilter innerBlurMaskFilter; 15238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka switch (thickness) { 15338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case EXTRA_THICK: 15438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka innerBlurMaskFilter = sExtraThickInnerBlurMaskFilter; 15538b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 15638b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case THICK: 15738b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka innerBlurMaskFilter = sThickInnerBlurMaskFilter; 15838b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 15938b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka case MEDIUM: 16038b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka innerBlurMaskFilter = sMediumInnerBlurMaskFilter; 16138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka break; 16238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka default: 16338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka throw new RuntimeException("Invalid blur thickness"); 16438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka } 16538b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka mBlurPaint.setMaskFilter(innerBlurMaskFilter); 16664a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung int[] thickInnerBlurOffset = new int[2]; 1675bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset); 1685f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 16964a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // mask out the inner blur 17064a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.setBitmap(thickInnerBlur); 1715bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen srcDstCanvas.drawBitmap(glowShape, -thickInnerBlurOffset[0], 17264a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung -thickInnerBlurOffset[1], mErasePaint); 17364a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(), 17464a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mErasePaint); 17564a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.drawRect(0, 0, thickInnerBlur.getWidth(), -thickInnerBlurOffset[1], 17664a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mErasePaint); 1775f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 17864a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // draw the inner and outer blur 17964a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.setBitmap(srcDst); 1802a9e70655f5885549acfdb6e770d2516bc8c87e3Michael Jurka srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR); 18164a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mHolographicPaint.setColor(color); 18264a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0], thickInnerBlurOffset[1], 18364a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mHolographicPaint); 18464a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung srcDstCanvas.drawBitmap(thickOuterBlur, outerBlurOffset[0], outerBlurOffset[1], 18564a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mHolographicPaint); 18664a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung 18764a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // draw the bright outline 18864a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mHolographicPaint.setColor(outlineColor); 18938b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1], 19064a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung mHolographicPaint); 19164a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung 19264a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung // cleanup 193aaf473c2bb6329b3b09ed2e19de6aae26077050cAdam Cohen srcDstCanvas.setBitmap(null); 19438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka brightOutline.recycle(); 19564a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung thickOuterBlur.recycle(); 19664a3cd4f204dd5f3676249d50aa0881b2e279b1fWinson Chung thickInnerBlur.recycle(); 1975bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen glowShape.recycle(); 1985f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 1995bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 20038b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka void applyExtraThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 20138b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka int outlineColor) { 20238b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, EXTRA_THICK); 20338b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka } 20438b4f7c5eab773ad36048b5ab8713750dcaaf748Michael Jurka 2055bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen void applyThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 2065bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen int outlineColor) { 2075bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, THICK); 2085bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen } 2095bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 2105bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 2118c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka int outlineColor, boolean clipAlpha) { 2128c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, clipAlpha, 2138db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng MEDIUM); 2148db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng } 2158db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng 2168db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, 2175bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen int outlineColor) { 2185bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, MEDIUM); 2195bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen } 2205bb50bdb13f5fc22f5febd9480e78222b26c6fe7Adam Cohen 2217da1025bd7f15b04cf55c79b73e94e5e1bc959d9Winson Chung} 222