Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29645115 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Removing shape detection in icon loader lib" into main

parents 9e4ab516 836a5759
Loading
Loading
Loading
Loading
+17 −32
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFracti

import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT;
import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
import static com.android.launcher3.icons.ShadowGenerator.ICON_SCALE_FOR_SHADOWS;

import static java.lang.annotation.RetentionPolicy.SOURCE;

@@ -22,7 +23,6 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@@ -95,20 +95,20 @@ public class BaseIconFactory implements AutoCloseable {
    @Nullable
    private ShadowGenerator mShadowGenerator;

    private final boolean mShapeDetection;

    // Shadow bitmap used as background for theme icons
    private Bitmap mWhiteShadowLayer;

    private Drawable mWrapperIcon;
    private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;

    private static int PLACEHOLDER_BACKGROUND_COLOR = Color.rgb(245, 245, 245);

    protected BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize,
            boolean shapeDetection) {
            boolean unused) {
        this(context, fullResIconDpi, iconBitmapSize);
    }

    public BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize) {
        mContext = context.getApplicationContext();
        mShapeDetection = shapeDetection;
        mFullResIconDpi = fullResIconDpi;
        mIconBitmapSize = iconBitmapSize;

@@ -120,10 +120,6 @@ public class BaseIconFactory implements AutoCloseable {
        clear();
    }

    public BaseIconFactory(Context context, int fullResIconDpi, int iconBitmapSize) {
        this(context, fullResIconDpi, iconBitmapSize, false);
    }

    protected void clear() {
        mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
    }
@@ -139,7 +135,7 @@ public class BaseIconFactory implements AutoCloseable {
    @NonNull
    public IconNormalizer getNormalizer() {
        if (mNormalizer == null) {
            mNormalizer = new IconNormalizer(mContext, mIconBitmapSize, mShapeDetection);
            mNormalizer = new IconNormalizer(mContext, mIconBitmapSize);
        }
        return mNormalizer;
    }
@@ -232,7 +228,7 @@ public class BaseIconFactory implements AutoCloseable {
            // Need to convert to Adaptive Icon with insets to avoid cropping.
            tempIcon = createShapedAdaptiveIcon(bitmapDrawable.getBitmap());
        }
        AdaptiveIconDrawable adaptiveIcon = normalizeAndWrapToAdaptiveIcon(tempIcon, null, scale);
        AdaptiveIconDrawable adaptiveIcon = normalizeAndWrapToAdaptiveIcon(tempIcon, scale);
        Bitmap bitmap = createIconBitmap(adaptiveIcon, scale[0],
                options == null ? MODE_WITH_SHADOW : options.mGenerationMode);

@@ -298,11 +294,9 @@ public class BaseIconFactory implements AutoCloseable {

    @NonNull
    public Bitmap createScaledBitmap(@NonNull Drawable icon, @BitmapGenerationMode int mode) {
        RectF iconBounds = new RectF();
        float[] scale = new float[1];
        icon = normalizeAndWrapToAdaptiveIcon(icon, iconBounds, scale);
        return createIconBitmap(icon,
                Math.min(scale[0], ShadowGenerator.getScaleForBounds(iconBounds)), mode);
        icon = normalizeAndWrapToAdaptiveIcon(icon, scale);
        return createIconBitmap(icon, Math.min(scale[0], ICON_SCALE_FOR_SHADOWS), mode);
    }

    /**
@@ -313,17 +307,14 @@ public class BaseIconFactory implements AutoCloseable {
    }

    @Nullable
    protected AdaptiveIconDrawable normalizeAndWrapToAdaptiveIcon(@Nullable Drawable icon,
            @Nullable final RectF outIconBounds, @NonNull final float[] outScale) {
    protected AdaptiveIconDrawable normalizeAndWrapToAdaptiveIcon(
            @Nullable Drawable icon, @NonNull final float[] outScale) {
        if (icon == null) {
            return null;
        }

        AdaptiveIconDrawable adaptiveIcon;
        float scale;
        adaptiveIcon = wrapToAdaptiveIcon(icon, outIconBounds);
        scale = getNormalizer().getScale(adaptiveIcon, outIconBounds, null, null);
        outScale[0] = scale;
        AdaptiveIconDrawable adaptiveIcon = wrapToAdaptiveIcon(icon);
        outScale[0] = getNormalizer().getScale(adaptiveIcon);
        return adaptiveIcon;
    }

@@ -348,8 +339,7 @@ public class BaseIconFactory implements AutoCloseable {
    /**
     * Wraps the provided icon in an adaptive icon drawable
     */
    public AdaptiveIconDrawable wrapToAdaptiveIcon(@NonNull Drawable icon,
            @Nullable final RectF outIconBounds) {
    public AdaptiveIconDrawable wrapToAdaptiveIcon(@NonNull Drawable icon) {
        if (icon instanceof AdaptiveIconDrawable aid) {
            return aid;
        } else {
@@ -357,13 +347,8 @@ public class BaseIconFactory implements AutoCloseable {
            AdaptiveIconDrawable dr = new AdaptiveIconDrawable(
                    new ColorDrawable(mWrapperBackgroundColor), foreground);
            dr.setBounds(0, 0, 1, 1);
            boolean[] outShape = new boolean[1];
            float scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape);
            if (!outShape[0]) {
            float scale = getNormalizer().getScale(icon);
            foreground.setDrawable(createScaledDrawable(icon, scale * LEGACY_ICON_SCALE));
            } else {
                foreground.setDrawable(createScaledDrawable(icon, 1 - getExtraInsetFraction()));
            }
            return dr;
        }
    }
+1 −3
Original line number Diff line number Diff line
@@ -77,9 +77,7 @@ public class BubbleIconFactory extends BaseIconFactory {
        if (outScale == null) {
            outScale = new float[1];
        }
        icon = normalizeAndWrapToAdaptiveIcon(icon,
                null /* outscale */,
                outScale);
        icon = normalizeAndWrapToAdaptiveIcon(icon, outScale);
        return createIconBitmap(icon, outScale[0], MODE_WITH_SHADOW);
    }

+6 −38
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.launcher3.icons;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -28,17 +27,15 @@ import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;

import java.nio.ByteBuffer;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.nio.ByteBuffer;

public class IconNormalizer {

@@ -72,11 +69,8 @@ public class IconNormalizer {
    private final Paint mPaintMaskShapeOutline;
    private final byte[] mPixels;

    private final RectF mAdaptiveIconBounds;
    private float mAdaptiveIconScale;

    private boolean mEnableShapeDetection;

    // for each y, stores the position of the leftmost x and the rightmost x
    private final float[] mLeftBorder;
    private final float[] mRightBorder;
@@ -85,7 +79,7 @@ public class IconNormalizer {
    private final Matrix mMatrix;

    /** package private **/
    IconNormalizer(Context context, int iconBitmapSize, boolean shapeDetection) {
    IconNormalizer(Context context, int iconBitmapSize) {
        // Use twice the icon size as maximum size to avoid scaling down twice.
        mMaxSize = iconBitmapSize * 2;
        mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8);
@@ -94,7 +88,6 @@ public class IconNormalizer {
        mLeftBorder = new float[mMaxSize];
        mRightBorder = new float[mMaxSize];
        mBounds = new Rect();
        mAdaptiveIconBounds = new RectF();

        mPaintMaskShape = new Paint();
        mPaintMaskShape.setColor(Color.RED);
@@ -111,7 +104,6 @@ public class IconNormalizer {
        mShapePath = new Path();
        mMatrix = new Matrix();
        mAdaptiveIconScale = SCALE_NOT_INITIALIZED;
        mEnableShapeDetection = shapeDetection;
    }

    private static float getScale(float hullArea, float boundingArea, float fullArea) {
@@ -133,7 +125,7 @@ public class IconNormalizer {
     * @param size Canvas size to use
     */
    @TargetApi(Build.VERSION_CODES.O)
    public static float normalizeAdaptiveIcon(Drawable d, int size, @Nullable RectF outBounds) {
    public static float normalizeAdaptiveIcon(Drawable d, int size) {
        Rect tmpBounds = new Rect(d.getBounds());
        d.setBounds(0, 0, size, size);

@@ -141,17 +133,7 @@ public class IconNormalizer {
        Region region = new Region();
        region.setPath(path, new Region(0, 0, size, size));

        Rect hullBounds = region.getBounds();
        int hullArea = GraphicsUtils.getArea(region);

        if (outBounds != null) {
            float sizeF = size;
            outBounds.set(
                    hullBounds.left / sizeF,
                    hullBounds.top / sizeF,
                    1 - (hullBounds.right / sizeF),
                    1 - (hullBounds.bottom / sizeF));
        }
        d.setBounds(tmpBounds);
        return getScale(hullArea, hullArea, size * size);
    }
@@ -233,17 +215,11 @@ public class IconNormalizer {
     *
     * This closeness is used to determine the ratio of hull area to the full icon size.
     * Refer {@link #MAX_CIRCLE_AREA_FACTOR} and {@link #MAX_SQUARE_AREA_FACTOR}
     *
     * @param outBounds optional rect to receive the fraction distance from each edge.
     */
    public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds,
            @Nullable Path path, @Nullable boolean[] outMaskShape) {
    public synchronized float getScale(@NonNull Drawable d) {
        if (d instanceof AdaptiveIconDrawable) {
            if (mAdaptiveIconScale == SCALE_NOT_INITIALIZED) {
                mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize, mAdaptiveIconBounds);
            }
            if (outBounds != null) {
                outBounds.set(mAdaptiveIconBounds);
                mAdaptiveIconScale = normalizeAdaptiveIcon(d, mMaxSize);
            }
            return mAdaptiveIconScale;
        }
@@ -334,14 +310,6 @@ public class IconNormalizer {
        mBounds.top = topY;
        mBounds.bottom = bottomY;

        if (outBounds != null) {
            outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height,
                    1 - ((float) mBounds.right) / width,
                    1 - ((float) mBounds.bottom) / height);
        }
        if (outMaskShape != null && mEnableShapeDetection && outMaskShape.length > 0) {
            outMaskShape[0] = isShape(path);
        }
        // Area of the rectangle required to fit the convex hull
        float rectArea = (bottomY + 1 - topY) * (rightX + 1 - leftX);
        return getScale(area, rectArea, width * height);
+5 −24
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ public class ShadowGenerator {
    private static final float HALF_DISTANCE = 0.5f;
    private static final int AMBIENT_SHADOW_ALPHA = 25;

    // Amount by which an icon should be scaled down to make room for shadows.
    // We are ignoring KEY_SHADOW_DISTANCE because regular icons also ignore this: b/298203449
    public static final float ICON_SCALE_FOR_SHADOWS =
            (HALF_DISTANCE - BLUR_FACTOR) / HALF_DISTANCE;

    private final int mIconSize;

    private final Paint mBlurPaint;
@@ -95,30 +100,6 @@ public class ShadowGenerator {
        }
    }

    /**
     * Returns the minimum amount by which an icon with {@param bounds} should be scaled
     * so that the shadows do not get clipped.
     */
    public static float getScaleForBounds(RectF bounds) {
        float scale = 1;

        if (ENABLE_SHADOWS) {
            // For top, left & right, we need same space.
            float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top);
            if (minSide < BLUR_FACTOR) {
                scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide);
            }

            // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the moment b/298203449
            float bottomSpace = BLUR_FACTOR;
            if (bounds.bottom < bottomSpace) {
                scale = Math.min(scale,
                        (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom));
            }
        }
        return scale;
    }

    public static class Builder {

        public final RectF bounds = new RectF();
+1 −6
Original line number Diff line number Diff line
@@ -51,12 +51,7 @@ class MonoIconThemeController : IconThemeController {
        val mono = getMonochromeDrawable(icon, info)
        if (mono != null) {
            val scale =
                factory.normalizer.getScale(
                    AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null),
                    null,
                    null,
                    null,
                )
                factory.normalizer.getScale(AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null))
            return MonoThemedBitmap(
                factory.createIconBitmap(mono, scale, BaseIconFactory.MODE_ALPHA),
                factory.whiteShadowLayer,