Loading iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +28 −25 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ import static com.android.launcher3.icons.BitmapInfo.FLAG_FULL_BLEED; import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT; import static com.android.launcher3.icons.GraphicsUtils.generateIconShape; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR; import static java.lang.annotation.RetentionPolicy.SOURCE; Loading Loading @@ -446,35 +445,39 @@ public class BaseIconFactory implements AutoCloseable { @Nullable Bitmap targetBitmap, boolean isFullBleed) { final int size = mIconBitmapSize; mOldBounds.set(icon.getBounds()); boolean isFullBleedEnabled = isFullBleed && Flags.enableLauncherIconShapes(); if (icon instanceof AdaptiveIconDrawable aid) { // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the // moment b/298203449 int offset = isFullBleedEnabled ? 0 : Math.max((int) Math.ceil(BLUR_FACTOR * size), Math.round(size * (1 - scale) / 2)); // b/211896569: AdaptiveIconDrawable do not work properly for non top-left bounds int newBounds = size - offset * 2; icon.setBounds(0, 0, newBounds, newBounds); int count = canvas.save(); canvas.translate(offset, offset); if ((bitmapGenerationMode == MODE_WITH_SHADOW || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW) && !isFullBleedEnabled) { getShadowGenerator().addPathShadow(aid.getIconMask(), canvas); } if (icon instanceof AdaptiveIconDrawable aid) { icon.setBounds(0, 0, size, size); if (icon instanceof Extender extender) { extender.drawForPersistence(); } drawAdaptiveIcon(canvas, aid, isFullBleedEnabled, getShapePath(aid, icon.getBounds())); canvas.restoreToCount(count); if (isFullBleed && Flags.enableLauncherIconShapes()) { canvas.drawColor(Color.BLACK); if (aid.getBackground() != null) { aid.getBackground().draw(canvas); } if (aid.getForeground() != null) { aid.getForeground().draw(canvas); } } else { GraphicsUtils.resizeToContentSize(canvas, icon.getBounds(), size, size, c -> { if ((bitmapGenerationMode == MODE_WITH_SHADOW || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW)) { getShadowGenerator().addPathShadow(aid.getIconMask(), c); } boolean shouldDrawDefaultShape = !isFullBleed && mDrawFullBleedIcons; // TODO: b/421884219 Temporarily keep old implementation until migrated if (shouldDrawDefaultShape) { // New Icon shapes path, used for non-full bleed icons icon.draw(canvas); } else { drawShapedAdaptiveIcon(canvas, aid, getShapePath(aid, icon.getBounds())); } return null; }); } } else { if (icon instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; if (icon instanceof BitmapDrawable bitmapDrawable) { Bitmap b = bitmapDrawable.getBitmap(); if (b != null && b.getDensity() == Bitmap.DENSITY_NONE) { bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics()); Loading iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.kt +13 −23 Original line number Diff line number Diff line Loading @@ -35,13 +35,10 @@ import android.graphics.RegionIterator import android.util.Log import androidx.annotation.ColorInt import androidx.core.graphics.ColorUtils.compositeColors import com.android.launcher3.icons.GraphicsUtils.resize import com.android.launcher3.icons.BitmapRenderer.createHardwareBitmap import com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR import com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR import java.io.ByteArrayOutputStream import java.io.IOException import kotlin.math.ceil import kotlin.math.max object GraphicsUtils { private const val TAG = "GraphicsUtils" Loading Loading @@ -133,6 +130,7 @@ object GraphicsUtils { * the [block]. It also scales down the drawing by [ICON_VISIBLE_AREA_FACTOR] to account for * icon normalization. */ @JvmStatic inline fun Canvas.resizeToContentSize( bounds: Rect, sizeX: Float, Loading @@ -150,25 +148,17 @@ object GraphicsUtils { * [size]] */ @JvmStatic fun generateIconShape(size: Int, shapePath: Path): IconShape { // Generate shadow layer: // Based on adaptive icon drawing in BaseIconFactory val offset = max( ceil((BLUR_FACTOR * size)).toInt(), Math.round(size * (1 - ICON_VISIBLE_AREA_FACTOR) / 2), fun generateIconShape(size: Int, shapePath: Path): IconShape = IconShape( pathSize = size, path = shapePath, shadowLayer = createHardwareBitmap(size, size) { it.resizeToContentSize(Rect(0, 0, size, size), size.toFloat()) { ShadowGenerator(size).addPathShadow(shapePath, this) } }, ) val shadowLayer = BitmapRenderer.createHardwareBitmap(size, size) { canvas: Canvas -> canvas.transformed { canvas.translate(offset.toFloat(), offset.toFloat()) val drawnPathSize = size - offset * 2 val drawnPath = shapePath.resize(size, drawnPathSize) ShadowGenerator(size).addPathShadow(drawnPath, canvas) } } return IconShape(pathSize = size, path = shapePath, shadowLayer = shadowLayer) } /** Returns a color filter which is equivalent to [filter] x BlendModeFilter with [color] */ fun getColorMultipliedFilter(color: Int, filter: ColorFilter?): ColorFilter? { Loading Loading
iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +28 −25 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ import static com.android.launcher3.icons.BitmapInfo.FLAG_FULL_BLEED; import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT; import static com.android.launcher3.icons.GraphicsUtils.generateIconShape; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR; import static java.lang.annotation.RetentionPolicy.SOURCE; Loading Loading @@ -446,35 +445,39 @@ public class BaseIconFactory implements AutoCloseable { @Nullable Bitmap targetBitmap, boolean isFullBleed) { final int size = mIconBitmapSize; mOldBounds.set(icon.getBounds()); boolean isFullBleedEnabled = isFullBleed && Flags.enableLauncherIconShapes(); if (icon instanceof AdaptiveIconDrawable aid) { // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the // moment b/298203449 int offset = isFullBleedEnabled ? 0 : Math.max((int) Math.ceil(BLUR_FACTOR * size), Math.round(size * (1 - scale) / 2)); // b/211896569: AdaptiveIconDrawable do not work properly for non top-left bounds int newBounds = size - offset * 2; icon.setBounds(0, 0, newBounds, newBounds); int count = canvas.save(); canvas.translate(offset, offset); if ((bitmapGenerationMode == MODE_WITH_SHADOW || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW) && !isFullBleedEnabled) { getShadowGenerator().addPathShadow(aid.getIconMask(), canvas); } if (icon instanceof AdaptiveIconDrawable aid) { icon.setBounds(0, 0, size, size); if (icon instanceof Extender extender) { extender.drawForPersistence(); } drawAdaptiveIcon(canvas, aid, isFullBleedEnabled, getShapePath(aid, icon.getBounds())); canvas.restoreToCount(count); if (isFullBleed && Flags.enableLauncherIconShapes()) { canvas.drawColor(Color.BLACK); if (aid.getBackground() != null) { aid.getBackground().draw(canvas); } if (aid.getForeground() != null) { aid.getForeground().draw(canvas); } } else { GraphicsUtils.resizeToContentSize(canvas, icon.getBounds(), size, size, c -> { if ((bitmapGenerationMode == MODE_WITH_SHADOW || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW)) { getShadowGenerator().addPathShadow(aid.getIconMask(), c); } boolean shouldDrawDefaultShape = !isFullBleed && mDrawFullBleedIcons; // TODO: b/421884219 Temporarily keep old implementation until migrated if (shouldDrawDefaultShape) { // New Icon shapes path, used for non-full bleed icons icon.draw(canvas); } else { drawShapedAdaptiveIcon(canvas, aid, getShapePath(aid, icon.getBounds())); } return null; }); } } else { if (icon instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; if (icon instanceof BitmapDrawable bitmapDrawable) { Bitmap b = bitmapDrawable.getBitmap(); if (b != null && b.getDensity() == Bitmap.DENSITY_NONE) { bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics()); Loading
iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.kt +13 −23 Original line number Diff line number Diff line Loading @@ -35,13 +35,10 @@ import android.graphics.RegionIterator import android.util.Log import androidx.annotation.ColorInt import androidx.core.graphics.ColorUtils.compositeColors import com.android.launcher3.icons.GraphicsUtils.resize import com.android.launcher3.icons.BitmapRenderer.createHardwareBitmap import com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR import com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR import java.io.ByteArrayOutputStream import java.io.IOException import kotlin.math.ceil import kotlin.math.max object GraphicsUtils { private const val TAG = "GraphicsUtils" Loading Loading @@ -133,6 +130,7 @@ object GraphicsUtils { * the [block]. It also scales down the drawing by [ICON_VISIBLE_AREA_FACTOR] to account for * icon normalization. */ @JvmStatic inline fun Canvas.resizeToContentSize( bounds: Rect, sizeX: Float, Loading @@ -150,25 +148,17 @@ object GraphicsUtils { * [size]] */ @JvmStatic fun generateIconShape(size: Int, shapePath: Path): IconShape { // Generate shadow layer: // Based on adaptive icon drawing in BaseIconFactory val offset = max( ceil((BLUR_FACTOR * size)).toInt(), Math.round(size * (1 - ICON_VISIBLE_AREA_FACTOR) / 2), fun generateIconShape(size: Int, shapePath: Path): IconShape = IconShape( pathSize = size, path = shapePath, shadowLayer = createHardwareBitmap(size, size) { it.resizeToContentSize(Rect(0, 0, size, size), size.toFloat()) { ShadowGenerator(size).addPathShadow(shapePath, this) } }, ) val shadowLayer = BitmapRenderer.createHardwareBitmap(size, size) { canvas: Canvas -> canvas.transformed { canvas.translate(offset.toFloat(), offset.toFloat()) val drawnPathSize = size - offset * 2 val drawnPath = shapePath.resize(size, drawnPathSize) ShadowGenerator(size).addPathShadow(drawnPath, canvas) } } return IconShape(pathSize = size, path = shapePath, shadowLayer = shadowLayer) } /** Returns a color filter which is equivalent to [filter] x BlendModeFilter with [color] */ fun getColorMultipliedFilter(color: Int, filter: ColorFilter?): ColorFilter? { Loading