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

Commit 13600f9e authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Don't cast shadows from gradients with transparent parts" into lmp-dev

parents efa5a01d c49e3ce6
Loading
Loading
Loading
Loading
+23 −15
Original line number Diff line number Diff line
@@ -18,15 +18,15 @@ package android.graphics;

import android.annotation.NonNull;
import android.graphics.drawable.Drawable;
import android.view.View;

/**
 * Defines a simple shape, used for bounding graphical regions.
 * <p>
 * Can be used with a View, or computed by a Drawable, to drive the shape of shadows cast by a
 * View, or to clip the contents of the View.
 * Can be computed for a View, or computed by a Drawable, to drive the shape of
 * shadows cast by a View, or to clip the contents of the View.
 *
 * @see View#setOutline(Outline)
 * @see android.view.ViewOutlineProvider
 * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
 * @see Drawable#getOutline(Outline)
 */
public final class Outline {
@@ -79,21 +79,27 @@ public final class Outline {

    /**
     * Returns whether the outline can be used to clip a View.
     * <p>
     * Currently, only Outlines that can be represented as a rectangle, circle,
     * or round rect support clipping.
     *
     * Currently, only outlines that can be represented as a rectangle, circle, or round rect
     * support clipping.
     *
     * @see {@link View#setClipToOutline(boolean)}
     * @see {@link android.view.View#setClipToOutline(boolean)}
     */
    public boolean canClip() {
        return !isEmpty() && mRect != null;
    }

    /**
     * Sets the alpha represented by the Outline.
     *
     * Content producing a fully opaque (alpha = 1.0f) outline is assumed by the drawing system
     * to fully cover content beneath it, meaning content beneath may be optimized away.
     * Sets the alpha represented by the Outline - the degree to which the
     * producer is guaranteed to be opaque over the Outline's shape.
     * <p>
     * An alpha value of <code>0.0f</code> either represents completely
     * transparent content, or content that isn't guaranteed to fill the shape
     * it publishes.
     * <p>
     * Content producing a fully opaque (alpha = <code>1.0f</code>) outline is
     * assumed by the drawing system to fully cover content beneath it,
     * meaning content beneath may be optimized away.
     */
    public void setAlpha(float alpha) {
        mAlpha = alpha;
@@ -130,7 +136,8 @@ public final class Outline {
    }

    /**
     * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
     * Sets the Outline to the rounded rect defined by the input rect, and
     * corner radius.
     */
    public void setRect(int left, int top, int right, int bottom) {
        setRoundRect(left, top, right, bottom, 0.0f);
@@ -145,7 +152,7 @@ public final class Outline {

    /**
     * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
     *
     * <p>
     * Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)}
     */
    public void setRoundRect(int left, int top, int right, int bottom, float radius) {
@@ -196,7 +203,8 @@ public final class Outline {
    }

    /**
     * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
     * Sets the Constructs an Outline from a
     * {@link android.graphics.Path#isConvex() convex path}.
     */
    public void setConvexPath(@NonNull Path convexPath) {
        if (convexPath.isEmpty()) {
+15 −17
Original line number Diff line number Diff line
@@ -820,7 +820,7 @@ public class GradientDrawable extends Drawable {

    @Override
    public int getOpacity() {
        return (mAlpha == 255 && mGradientState.mOpaque) ?
        return (mAlpha == 255 && mGradientState.mOpaqueOverBounds) ?
                PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
    }

@@ -1413,7 +1413,8 @@ public class GradientDrawable extends Drawable {
    public void getOutline(Outline outline) {
        final GradientState st = mGradientState;
        final Rect bounds = getBounds();
        outline.setAlpha(mAlpha / 255.0f);
        // only report non-zero alpha if shape being drawn is opaque
        outline.setAlpha(st.mOpaqueOverShape ? (mAlpha / 255.0f) : 0.0f);

        switch (st.mShape) {
            case RECTANGLE:
@@ -1492,7 +1493,8 @@ public class GradientDrawable extends Drawable {
        private int mGradientRadiusType = RADIUS_TYPE_PIXELS;
        private boolean mUseLevel;
        private boolean mUseLevelForShape;
        private boolean mOpaque;
        private boolean mOpaqueOverBounds;
        private boolean mOpaqueOverShape;

        int[] mThemeAttrs;
        int[] mAttrSize;
@@ -1544,7 +1546,7 @@ public class GradientDrawable extends Drawable {
            mGradientRadiusType = state.mGradientRadiusType;
            mUseLevel = state.mUseLevel;
            mUseLevelForShape = state.mUseLevelForShape;
            mOpaque = state.mOpaque;
            mOpaqueOverBounds = state.mOpaqueOverBounds;
            mThemeAttrs = state.mThemeAttrs;
            mAttrSize = state.mAttrSize;
            mAttrGradient = state.mAttrGradient;
@@ -1606,40 +1608,36 @@ public class GradientDrawable extends Drawable {
        }

        private void computeOpacity() {
            if (mShape != RECTANGLE) {
                mOpaque = false;
                return;
            }

            if (mRadius > 0 || mRadiusArray != null) {
                mOpaque = false;
                return;
            }
            mOpaqueOverBounds = false;
            mOpaqueOverShape = false;

            // First test opacity of all colors
            if (mStrokeWidth > 0) {
                if (mStrokeColorStateList != null) {
                    if (!mStrokeColorStateList.isOpaque()) {
                        mOpaque = false;
                        return;
                    }
                }
            }

            if (mColorStateList != null && !mColorStateList.isOpaque()) {
                mOpaque = false;
                return;
            }

            if (mColors != null) {
                for (int i = 0; i < mColors.length; i++) {
                    if (!isOpaque(mColors[i])) {
                        mOpaque = false;
                        return;
                    }
                }
            }

            mOpaque = true;
            // Colors are opaque, so opaqueOverShape=true,
            mOpaqueOverShape = true;
            // and opaqueOverBounds=true if shape fills bounds
            mOpaqueOverBounds = mShape == RECTANGLE
                    && mRadius <= 0
                    && mRadiusArray == null;
        }

        private static boolean isOpaque(int color) {