19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt;
20519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.content.res.ColorStateList;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
2352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
254d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viveretteimport android.graphics.Color;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.DashPathEffect;
2887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viveretteimport android.graphics.Insets;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.LinearGradient;
30b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikimport android.graphics.Outline;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint;
32519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.Path;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
3443027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuff;
3543027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuffColorFilter;
36519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.RadialGradient;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Shader;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.SweepGradient;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R;
4652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
5317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * A Drawable with a color gradient for buttons, backgrounds, etc.
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
55dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code>&lt;shape></code> element. For more
56dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a
57dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_visible
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_shape
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadius
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thicknessRatio
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thickness
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_useLevel
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_width
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_height
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_startColor
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerColor
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_endColor
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_useLevel
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_angle
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_type
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerX
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerY
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_gradientRadius
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSolid_color
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_width
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_color
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashWidth
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashGap
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_left
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_top
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_right
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_bottom
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GradientDrawable extends Drawable {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shape is a rectangle, possibly with rounded corners
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RECTANGLE = 0;
9217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shape is an ellipse
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    public static final int OVAL = 1;
9717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shape is a line
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int LINE = 2;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shape is a ring.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RING = 3;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gradient is linear (default.)
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int LINEAR_GRADIENT = 0;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gradient is circular.
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RADIAL_GRADIENT = 1;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gradient is a sweep.
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int SWEEP_GRADIENT  = 2;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
123b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    /** Radius is in pixels. */
124b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    private static final int RADIUS_TYPE_PIXELS = 0;
125b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
126b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    /** Radius is a fraction of the base size. */
127b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    private static final int RADIUS_TYPE_FRACTION = 1;
128b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
129b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    /** Radius is a fraction of the bounds size. */
130b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette    private static final int RADIUS_TYPE_FRACTION_PARENT = 2;
131b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
13252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f;
13352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private static final float DEFAULT_THICKNESS_RATIO = 9.0f;
13452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private GradientState mGradientState;
13617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1376a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik    private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Rect mPadding;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Paint mStrokePaint;   // optional, set by the caller
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ColorFilter mColorFilter;   // optional, set by the caller
14143027b7bca554818cc4223389747d661819d5706Alan Viverette    private PorterDuffColorFilter mTintFilter;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAlpha = 0xFF;  // modified by the caller
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Path mPath = new Path();
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final RectF mRect = new RectF();
146e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Paint mLayerPaint;    // internal, used if we use saveLayer()
14845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette    private boolean mGradientIsDirty;
149684385ddde2ac0c26de0862390ad713aff3fb149Romain Guy    private boolean mMutated;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Path mRingPath;
1511041aded2df45094c36831028245fb7c5e9b67b7Romain Guy    private boolean mPathIsDirty = true;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1533aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase    /** Current gradient radius, valid when {@link #mGradientIsDirty} is false. */
154861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette    private float mGradientRadius;
155861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Controls how the gradient is oriented relative to the drawable's bounds
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Orientation {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the top to the bottom */
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TOP_BOTTOM,
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the top-right to the bottom-left */
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TR_BL,
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the right to the left */
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RIGHT_LEFT,
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the bottom-right to the top-left */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        BR_TL,
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the bottom to the top */
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        BOTTOM_TOP,
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the bottom-left to the top-right */
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        BL_TR,
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the left to the right */
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LEFT_RIGHT,
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** draw the gradient from the top-left to the bottom-right */
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TL_BR,
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public GradientDrawable() {
17945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        this(new GradientState(Orientation.TOP_BOTTOM, null), null);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new gradient drawable given an orientation and an array
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of colors for the gradient.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18680756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public GradientDrawable(Orientation orientation, @ColorInt int[] colors) {
18745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        this(new GradientState(orientation, colors), null);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPadding != null) {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.set(mPadding);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.getPadding(padding);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Specify radii for each of the 4 corners. For each corner, the array
2028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are ordered
2038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * top-left, top-right, bottom-right, bottom-left. This property
2048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * is honored only when the shape is of type {@link #RECTANGLE}.</p>
2058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
2068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
2078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
2088bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2098bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param radii 4 pairs of X and Y radius for each corner, specified in pixels.
2108bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *              The length of this array must be >= 8
2118bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2128bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
2138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #setCornerRadii(float[])
2148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #setShape(int)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCornerRadii(float[] radii) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.setCornerRadii(radii);
2181041aded2df45094c36831028245fb7c5e9b67b7Romain Guy        mPathIsDirty = true;
2199891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2238bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Specify radius for the corners of the gradient. If this is > 0, then the
2248bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * drawable is drawn in a round-rectangle, rather than a rectangle. This property
2258bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * is honored only when the shape is of type {@link #RECTANGLE}.</p>
2268bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
2278bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
2288bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
2298bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2308bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param radius The radius in pixels of the corners of the rectangle shape
2318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
2338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #setCornerRadii(float[])
23417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setShape(int)
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCornerRadius(float radius) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.setCornerRadius(radius);
2381041aded2df45094c36831028245fb7c5e9b67b7Romain Guy        mPathIsDirty = true;
2399891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2418bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Set the stroke width and color for the drawable. If width is zero,
2448bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * then no stroke is drawn.</p>
2458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
2468bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
2478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
2488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param width The width in pixels of the stroke
2508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param color The color of the stroke
2518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
25317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setStroke(int, int, float, float)
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
25580756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setStroke(int width, @ColorInt int color) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setStroke(width, color, 0, 0);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2588bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
2598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
260a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * <p>Set the stroke width and color state list for the drawable. If width
261a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * is zero, then no stroke is drawn.</p>
262a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * <p><strong>Note</strong>: changing this property will affect all instances
263a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * of a drawable loaded from a resource. It is recommended to invoke
264a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * {@link #mutate()} before changing this property.</p>
265a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     *
266a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param width The width in pixels of the stroke
267a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param colorStateList The color state list of the stroke
268a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     *
269a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @see #mutate()
270a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @see #setStroke(int, ColorStateList, float, float)
271a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     */
272a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    public void setStroke(int width, ColorStateList colorStateList) {
273a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        setStroke(width, colorStateList, 0, 0);
274a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    }
275a211dd28b93473c452d68432c602d5209b01c178Alan Viverette
276a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    /**
2778bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Set the stroke width and color for the drawable. If width is zero,
2788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * then no stroke is drawn. This method can also be used to dash the stroke.</p>
2798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
2808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
2818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
2828bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param width The width in pixels of the stroke
2848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param color The color of the stroke
28517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
2868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param dashGap The gap in pixels between dashes
2878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
2888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
28917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setStroke(int, int)
2908bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
29180756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setStroke(int width, @ColorInt int color, float dashWidth, float dashGap) {
29240df78153987409dbf299b84da9784b69029e184Alan Viverette        mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap);
293a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        setStrokeInternal(width, color, dashWidth, dashGap);
294a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
296a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    /**
297a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * <p>Set the stroke width and color state list for the drawable. If width
298a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * is zero, then no stroke is drawn. This method can also be used to dash
299a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * the stroke.</p>
300a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * <p><strong>Note</strong>: changing this property will affect all instances
301a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * of a drawable loaded from a resource. It is recommended to invoke
302a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * {@link #mutate()} before changing this property.</p>
303a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     *
304a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param width The width in pixels of the stroke
305a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param colorStateList The color state list of the stroke
306a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
307a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @param dashGap The gap in pixels between dashes
308a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     *
309a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @see #mutate()
310a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     * @see #setStroke(int, ColorStateList)
311a211dd28b93473c452d68432c602d5209b01c178Alan Viverette     */
312a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    public void setStroke(
313a211dd28b93473c452d68432c602d5209b01c178Alan Viverette            int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
31440df78153987409dbf299b84da9784b69029e184Alan Viverette        mGradientState.setStroke(width, colorStateList, dashWidth, dashGap);
31540df78153987409dbf299b84da9784b69029e184Alan Viverette        final int color;
3167c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        if (colorStateList == null) {
31740df78153987409dbf299b84da9784b69029e184Alan Viverette            color = Color.TRANSPARENT;
3187c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        } else {
3197c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette            final int[] stateSet = getState();
32040df78153987409dbf299b84da9784b69029e184Alan Viverette            color = colorStateList.getColorForState(stateSet, 0);
3217c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        }
32240df78153987409dbf299b84da9784b69029e184Alan Viverette        setStrokeInternal(width, color, dashWidth, dashGap);
323a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    }
324a211dd28b93473c452d68432c602d5209b01c178Alan Viverette
325a211dd28b93473c452d68432c602d5209b01c178Alan Viverette    private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mStrokePaint == null)  {
3276a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokePaint.setStyle(Paint.Style.STROKE);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrokePaint.setStrokeWidth(width);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrokePaint.setColor(color);
33217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DashPathEffect e = null;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dashWidth > 0) {
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrokePaint.setPathEffect(e);
3389891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3408bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
3418bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
3428bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
3438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Sets the size of the shape drawn by this drawable.</p>
3448bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
3458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
3468bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
3478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param width The width of the shape used by this drawable
3498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param height The height of the shape used by this drawable
3508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
3528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #setGradientType(int)
3538bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSize(int width, int height) {
3551041aded2df45094c36831028245fb7c5e9b67b7Romain Guy        mGradientState.setSize(width, height);
3561041aded2df45094c36831028245fb7c5e9b67b7Romain Guy        mPathIsDirty = true;
3579891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
3608bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
3618bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Sets the type of shape used to draw the gradient.</p>
3628bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
3638bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
3648bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
3658bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3668bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param shape The desired shape for this drawable: {@link #LINE},
3678bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *              {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}
3688bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3698bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
3708bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setShape(int shape) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRingPath = null;
3731041aded2df45094c36831028245fb7c5e9b67b7Romain Guy        mPathIsDirty = true;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.setShape(shape);
3759891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
3798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Sets the type of gradient used by this drawable..</p>
3808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
3818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
3828bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
3838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param gradient The type of the gradient: {@link #LINEAR_GRADIENT},
3858bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *                 {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}
3868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
3878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
3888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGradientType(int gradient) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.setGradientType(gradient);
3913aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
3929891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3958bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
39617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * <p>Sets the center location of the gradient. The radius is honored only when
3978bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * the gradient type is set to {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}.</p>
3988bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
3998bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
4008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
4018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param x The x coordinate of the gradient's center
4038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param y The y coordinate of the gradient's center
4048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
4068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #setGradientType(int)
4078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGradientCenter(float x, float y) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.setGradientCenter(x, y);
4103aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
4119891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
4158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Sets the radius of the gradient. The radius is honored only when the
4168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * gradient type is set to {@link #RADIAL_GRADIENT}.</p>
4178bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
4188bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
4198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
4208bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4218bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param gradientRadius The radius of the gradient in pixels
4228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4238bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
42417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setGradientType(int)
4258bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGradientRadius(float gradientRadius) {
427861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX);
4283aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
4299891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
433861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette     * Returns the radius of the gradient in pixels. The radius is valid only
434861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette     * when the gradient type is set to {@link #RADIAL_GRADIENT}.
435861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette     *
436861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette     * @return Radius in pixels.
437861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette     */
438861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette    public float getGradientRadius() {
439861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        if (mGradientState.mGradient != RADIAL_GRADIENT) {
440861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette            return 0;
441861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        }
442861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette
443861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        ensureValidRect();
444861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        return mGradientRadius;
445861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette    }
446861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette
447861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette    /**
4488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Sets whether or not this drawable will honor its <code>level</code>
4498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * property.</p>
4508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing this property will affect all instances
4518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
4528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing this property.</p>
4538bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4548bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param useLevel True if this drawable should honor its level, false otherwise
4558bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
4568bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
45717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setLevel(int)
45817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #getLevel()
4598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUseLevel(boolean useLevel) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGradientState.mUseLevel = useLevel;
4623aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
4639891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int modulateAlpha(int alpha) {
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int scale = mAlpha + (mAlpha >> 7);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return alpha * scale >> 8;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4718bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
4728bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * Returns the orientation of the gradient defined in this drawable.
4738bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
4748bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    public Orientation getOrientation() {
4758bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy        return mGradientState.mOrientation;
4768bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    }
4778bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
4788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
4798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p>Changes the orientation of the gradient defined in this drawable.</p>
4808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * <p><strong>Note</strong>: changing orientation will affect all instances
4818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
4828bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * {@link #mutate()} before changing the orientation.</p>
48317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     *
4848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param orientation The desired orientation (angle) of the gradient
48517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     *
48617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #mutate()
4878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
4888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    public void setOrientation(Orientation orientation) {
4898bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy        mGradientState.mOrientation = orientation;
4903aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
4918bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy        invalidateSelf();
4928bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    }
4938bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
4948bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
495e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * Sets the colors used to draw the gradient.
496e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * <p>
497e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * Each color is specified as an ARGB integer and the array must contain at
498e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * least 2 colors.
499e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * <p>
500e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * <strong>Note</strong>: changing colors will affect all instances of a
501e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * drawable loaded from a resource. It is recommended to invoke
502e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * {@link #mutate()} before changing the colors.
5038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
504e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette     * @param colors an array containing 2 or more ARGB colors
5058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
50617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setColor(int)
5078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
50880756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setColors(@ColorInt int[] colors) {
509e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        mGradientState.setGradientColors(colors);
5103aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
5118bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy        invalidateSelf();
5128bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    }
5138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
51516f1d81d47beb1e04504a76de66e2919dde08c33Alan Viverette    public void draw(Canvas canvas) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ensureValidRect()) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // nothing to draw
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // remember the alpha values, in case we temporarily overwrite them
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // when we modulate them with mAlpha
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int prevFillAlpha = mFillPaint.getAlpha();
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int prevStrokeAlpha = mStrokePaint != null ? mStrokePaint.getAlpha() : 0;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // compute the modulate alpha values
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int currFillAlpha = modulateAlpha(prevFillAlpha);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha);
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy        final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null &&
530e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy                mStrokePaint.getStrokeWidth() > 0;
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean haveFill = currFillAlpha > 0;
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final GradientState st = mGradientState;
53343027b7bca554818cc4223389747d661819d5706Alan Viverette        final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter;
53443027b7bca554818cc4223389747d661819d5706Alan Viverette
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*  we need a layer iff we're drawing both a fill and stroke, and the
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stroke is non-opaque, and our shapetype actually supports
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fill+stroke. Otherwise we can just draw the stroke (if any) on top
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            of the fill (if any) without worrying about blending artifacts.
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
54043027b7bca554818cc4223389747d661819d5706Alan Viverette        final boolean useLayer = haveStroke && haveFill && st.mShape != LINE &&
54143027b7bca554818cc4223389747d661819d5706Alan Viverette                 currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*  Drawing with a layer is slower than direct drawing, but it
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            allows us to apply paint effects like alpha and colorfilter to
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            the result of multiple separate draws. In our case, if the user
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            asks for a non-opaque alpha value (via setAlpha), and we're
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stroking, then we need to apply the alpha AFTER we've drawn
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            both the fill and the stroke.
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (useLayer) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mLayerPaint == null) {
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLayerPaint = new Paint();
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
55407c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette            mLayerPaint.setDither(st.mDither);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLayerPaint.setAlpha(mAlpha);
55643027b7bca554818cc4223389747d661819d5706Alan Viverette            mLayerPaint.setColorFilter(colorFilter);
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float rad = mStrokePaint.getStrokeWidth();
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.saveLayer(mRect.left - rad, mRect.top - rad,
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             mRect.right + rad, mRect.bottom + rad,
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             mLayerPaint, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // don't perform the filter in our individual paints
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // since the layer will do it for us
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFillPaint.setColorFilter(null);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokePaint.setColorFilter(null);
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*  if we're not using a layer, apply the dither/filter to our
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                individual paints
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            */
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFillPaint.setAlpha(currFillAlpha);
57207c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette            mFillPaint.setDither(st.mDither);
57343027b7bca554818cc4223389747d661819d5706Alan Viverette            mFillPaint.setColorFilter(colorFilter);
574e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (colorFilter != null && st.mSolidColors == null) {
575813680780f365648b39873fa26dfae0123d51aedChet Haase                mFillPaint.setColor(mAlpha << 24);
57641c769d9a8858ad20b0a6ed942a1cea19ba59d2dRomain Guy            }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (haveStroke) {
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStrokePaint.setAlpha(currStrokeAlpha);
57907c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette                mStrokePaint.setDither(st.mDither);
58043027b7bca554818cc4223389747d661819d5706Alan Viverette                mStrokePaint.setColorFilter(colorFilter);
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
583e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (st.mShape) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case RECTANGLE:
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (st.mRadiusArray != null) {
587e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik                    buildPathIfDirty();
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    canvas.drawPath(mPath, mFillPaint);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (haveStroke) {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        canvas.drawPath(mPath, mStrokePaint);
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
59261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                } else if (st.mRadius > 0.0f) {
5934e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed                    // since the caller is only giving us 1 value, we will force
5944e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed                    // it to be square if the rect is too small in one dimension
5954e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed                    // to show it. If we did nothing, Skia would clamp the rad
59661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    // independently along each axis, giving us a thin ellipse
5974e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed                    // if the rect were very wide but not very tall
598b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                    float rad = Math.min(st.mRadius,
599b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                            Math.min(mRect.width(), mRect.height()) * 0.5f);
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (haveStroke) {
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
60461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                } else {
60543027b7bca554818cc4223389747d661819d5706Alan Viverette                    if (mFillPaint.getColor() != 0 || colorFilter != null ||
606cf8675ee176a375f873792684d38a47f78348dffRomain Guy                            mFillPaint.getShader() != null) {
607cf8675ee176a375f873792684d38a47f78348dffRomain Guy                        canvas.drawRect(mRect, mFillPaint);
608cf8675ee176a375f873792684d38a47f78348dffRomain Guy                    }
60961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    if (haveStroke) {
61061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                        canvas.drawRect(mRect, mStrokePaint);
61161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case OVAL:
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                canvas.drawOval(mRect, mFillPaint);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (haveStroke) {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    canvas.drawOval(mRect, mStrokePaint);
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case LINE: {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                RectF r = mRect;
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                float y = r.centerY();
62371b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette                if (haveStroke) {
62471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette                    canvas.drawLine(r.left, y, r.right, y, mStrokePaint);
62571b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette                }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case RING:
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Path path = buildRing(st);
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                canvas.drawPath(path, mFillPaint);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (haveStroke) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    canvas.drawPath(path, mStrokePaint);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
63617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (useLayer) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.restore();
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFillPaint.setAlpha(prevFillAlpha);
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (haveStroke) {
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStrokePaint.setAlpha(prevStrokeAlpha);
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
646e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik
647e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik    private void buildPathIfDirty() {
648e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik        final GradientState st = mGradientState;
6493aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        if (mPathIsDirty) {
6503aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase            ensureValidRect();
651e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik            mPath.reset();
652e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik            mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW);
6533aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase            mPathIsDirty = false;
654e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik        }
655e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik    }
656e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Path buildRing(GradientState st) {
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPathIsDirty = false;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f;
66217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RectF bounds = new RectF(mRect);
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float x = bounds.width() / 2.0f;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float y = bounds.height() / 2.0f;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float thickness = st.mThickness != -1 ?
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                st.mThickness : bounds.width() / st.mThicknessRatio;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // inner radius
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float radius = st.mInnerRadius != -1 ?
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                st.mInnerRadius : bounds.width() / st.mInnerRadiusRatio;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RectF innerBounds = new RectF(bounds);
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        innerBounds.inset(x - radius, y - radius);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bounds = new RectF(innerBounds);
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bounds.inset(-thickness, -thickness);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRingPath == null) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRingPath = new Path();
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
683b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            mRingPath.reset();
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Path ringPath = mRingPath;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // arcTo treats the sweep angle mod 360, so check for that, since we
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // think 360 means draw the entire oval
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sweep < 360 && sweep > -360) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.setFillType(Path.FillType.EVEN_ODD);
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // inner top
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.moveTo(x + radius, y);
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // outer top
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.lineTo(x + radius + thickness, y);
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // outer arc
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.arcTo(bounds, 0.0f, sweep, false);
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // inner arc
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.arcTo(innerBounds, sweep, -sweep, false);
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.close();
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // add the entire ovals
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.addOval(bounds, Path.Direction.CW);
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ringPath.addOval(innerBounds, Path.Direction.CCW);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ringPath;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7098bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy    /**
710519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * <p>Changes this drawable to use a single color instead of a gradient.</p>
711e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy     * <p><strong>Note</strong>: changing color will affect all instances
7128bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * of a drawable loaded from a resource. It is recommended to invoke
713e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy     * {@link #mutate()} before changing the color.</p>
7148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
7158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @param argb The color used to fill the shape
7168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     *
7178bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     * @see #mutate()
71817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette     * @see #setColors(int[])
7198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy     */
72080756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setColor(@ColorInt int argb) {
721e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        mGradientState.setSolidColors(ColorStateList.valueOf(argb));
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFillPaint.setColor(argb);
7239891e1fce5f29d0421d34aa481037417bd70853dChet Haase        invalidateSelf();
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
726519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    /**
727519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * Changes this drawable to use a single color state list instead of a
7287c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette     * gradient. Calling this method with a null argument will clear the color
7297c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette     * and is equivalent to calling {@link #setColor(int)} with the argument
7307c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette     * {@link Color#TRANSPARENT}.
731519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * <p>
732519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * <strong>Note</strong>: changing color will affect all instances of a
733519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * drawable loaded from a resource. It is recommended to invoke
734519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * {@link #mutate()} before changing the color.</p>
735519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     *
736519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * @param colorStateList The color state list used to fill the shape
737519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     * @see #mutate()
738519494e207322581075c8ea884fde9d33bb9209eAlan Viverette     */
739519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    public void setColor(ColorStateList colorStateList) {
740e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        mGradientState.setSolidColors(colorStateList);
74140df78153987409dbf299b84da9784b69029e184Alan Viverette        final int color;
7427c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        if (colorStateList == null) {
74340df78153987409dbf299b84da9784b69029e184Alan Viverette            color = Color.TRANSPARENT;
7447c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        } else {
74540df78153987409dbf299b84da9784b69029e184Alan Viverette            final int[] stateSet = getState();
74640df78153987409dbf299b84da9784b69029e184Alan Viverette            color = colorStateList.getColorForState(stateSet, 0);
7477c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette        }
74840df78153987409dbf299b84da9784b69029e184Alan Viverette        mFillPaint.setColor(color);
74940df78153987409dbf299b84da9784b69029e184Alan Viverette        invalidateSelf();
750519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    }
751519494e207322581075c8ea884fde9d33bb9209eAlan Viverette
752519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    @Override
75312b97f5d2b15194ed6673c9838b13c8312157709Alan Viverette    protected boolean onStateChange(int[] stateSet) {
754a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        boolean invalidateSelf = false;
755a211dd28b93473c452d68432c602d5209b01c178Alan Viverette
756a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        final GradientState s = mGradientState;
757e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        final ColorStateList solidColors = s.mSolidColors;
758e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        if (solidColors != null) {
759e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            final int newColor = solidColors.getColorForState(stateSet, 0);
760519494e207322581075c8ea884fde9d33bb9209eAlan Viverette            final int oldColor = mFillPaint.getColor();
761519494e207322581075c8ea884fde9d33bb9209eAlan Viverette            if (oldColor != newColor) {
762519494e207322581075c8ea884fde9d33bb9209eAlan Viverette                mFillPaint.setColor(newColor);
763616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette                invalidateSelf = true;
764a211dd28b93473c452d68432c602d5209b01c178Alan Viverette            }
765a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        }
766a211dd28b93473c452d68432c602d5209b01c178Alan Viverette
767616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette        final Paint strokePaint = mStrokePaint;
768616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette        if (strokePaint != null) {
769e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            final ColorStateList strokeColors = s.mStrokeColors;
770e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (strokeColors != null) {
771e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                final int newColor = strokeColors.getColorForState(stateSet, 0);
772e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                final int oldColor = strokePaint.getColor();
773e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                if (oldColor != newColor) {
774e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    strokePaint.setColor(newColor);
775616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette                    invalidateSelf = true;
776616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette                }
777519494e207322581075c8ea884fde9d33bb9209eAlan Viverette            }
778519494e207322581075c8ea884fde9d33bb9209eAlan Viverette        }
779519494e207322581075c8ea884fde9d33bb9209eAlan Viverette
78043027b7bca554818cc4223389747d661819d5706Alan Viverette        if (s.mTint != null && s.mTintMode != null) {
78143027b7bca554818cc4223389747d661819d5706Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode);
78243027b7bca554818cc4223389747d661819d5706Alan Viverette            invalidateSelf = true;
78343027b7bca554818cc4223389747d661819d5706Alan Viverette        }
78443027b7bca554818cc4223389747d661819d5706Alan Viverette
785a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        if (invalidateSelf) {
786a211dd28b93473c452d68432c602d5209b01c178Alan Viverette            invalidateSelf();
787a211dd28b93473c452d68432c602d5209b01c178Alan Viverette            return true;
788a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        }
789a211dd28b93473c452d68432c602d5209b01c178Alan Viverette
790a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        return false;
791519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    }
792519494e207322581075c8ea884fde9d33bb9209eAlan Viverette
793519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    @Override
794519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    public boolean isStateful() {
795a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        final GradientState s = mGradientState;
796a211dd28b93473c452d68432c602d5209b01c178Alan Viverette        return super.isStateful()
797e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                || (s.mSolidColors != null && s.mSolidColors.isStateful())
798e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                || (s.mStrokeColors != null && s.mStrokeColors.isStateful())
79943027b7bca554818cc4223389747d661819d5706Alan Viverette                || (s.mTint != null && s.mTint.isStateful());
800519494e207322581075c8ea884fde9d33bb9209eAlan Viverette    }
801519494e207322581075c8ea884fde9d33bb9209eAlan Viverette
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
804e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
8099891e1fce5f29d0421d34aa481037417bd70853dChet Haase        if (alpha != mAlpha) {
8109891e1fce5f29d0421d34aa481037417bd70853dChet Haase            mAlpha = alpha;
8119891e1fce5f29d0421d34aa481037417bd70853dChet Haase            invalidateSelf();
8129891e1fce5f29d0421d34aa481037417bd70853dChet Haase        }
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
816b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
817b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        return mAlpha;
818b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
819b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
820b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
82207c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette        if (dither != mGradientState.mDither) {
82307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette            mGradientState.mDither = dither;
8249891e1fce5f29d0421d34aa481037417bd70853dChet Haase            invalidateSelf();
8259891e1fce5f29d0421d34aa481037417bd70853dChet Haase        }
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
82938b5f597de96cd892add9017dc810212f549bf68John Spurlock    public ColorFilter getColorFilter() {
83038b5f597de96cd892add9017dc810212f549bf68John Spurlock        return mColorFilter;
83138b5f597de96cd892add9017dc810212f549bf68John Spurlock    }
83238b5f597de96cd892add9017dc810212f549bf68John Spurlock
83338b5f597de96cd892add9017dc810212f549bf68John Spurlock    @Override
834bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik    public void setColorFilter(ColorFilter colorFilter) {
835bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik        if (colorFilter != mColorFilter) {
836bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik            mColorFilter = colorFilter;
8379891e1fce5f29d0421d34aa481037417bd70853dChet Haase            invalidateSelf();
8389891e1fce5f29d0421d34aa481037417bd70853dChet Haase        }
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
84243027b7bca554818cc4223389747d661819d5706Alan Viverette    public void setTintList(ColorStateList tint) {
84343027b7bca554818cc4223389747d661819d5706Alan Viverette        mGradientState.mTint = tint;
84443027b7bca554818cc4223389747d661819d5706Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode);
84543027b7bca554818cc4223389747d661819d5706Alan Viverette        invalidateSelf();
84643027b7bca554818cc4223389747d661819d5706Alan Viverette    }
84743027b7bca554818cc4223389747d661819d5706Alan Viverette
84843027b7bca554818cc4223389747d661819d5706Alan Viverette    @Override
84943027b7bca554818cc4223389747d661819d5706Alan Viverette    public void setTintMode(PorterDuff.Mode tintMode) {
85043027b7bca554818cc4223389747d661819d5706Alan Viverette        mGradientState.mTintMode = tintMode;
85143027b7bca554818cc4223389747d661819d5706Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode);
85243027b7bca554818cc4223389747d661819d5706Alan Viverette        invalidateSelf();
85343027b7bca554818cc4223389747d661819d5706Alan Viverette    }
85443027b7bca554818cc4223389747d661819d5706Alan Viverette
85543027b7bca554818cc4223389747d661819d5706Alan Viverette    @Override
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
857888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ?
8580a1c6f021be032f5aecb341c2794efb06c0a8a0dAlan Viverette                PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect r) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onBoundsChange(r);
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRingPath = null;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPathIsDirty = true;
8663aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onLevelChange(level);
8723aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        mGradientIsDirty = true;
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPathIsDirty = true;
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invalidateSelf();
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8793aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase     * This checks mGradientIsDirty, and if it is true, recomputes both our drawing
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rectangle (mRect) and the gradient itself, since it depends on our
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rectangle too.
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting rectangle is not empty, false otherwise
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean ensureValidRect() {
8853aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase        if (mGradientIsDirty) {
8863aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase            mGradientIsDirty = false;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect bounds = getBounds();
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float inset = 0;
89017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mStrokePaint != null) {
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inset = mStrokePaint.getStrokeWidth() * 0.5f;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final GradientState st = mGradientState;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRect.set(bounds.left + inset, bounds.top + inset,
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      bounds.right - inset, bounds.bottom - inset);
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
900e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            final int[] gradientColors = st.mGradientColors;
901e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (gradientColors != null) {
902e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                final RectF r = mRect;
903e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                final float x0, x1, y0, y1;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (st.mGradient == LINEAR_GRADIENT) {
9067979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik                    final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (st.mOrientation) {
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case TOP_BOTTOM:
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.left;            y0 = r.top;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = x0;                y1 = level * r.bottom;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case TR_BL:
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.right;           y0 = r.top;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.left;    y1 = level * r.bottom;
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case RIGHT_LEFT:
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.right;           y0 = r.top;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.left;    y1 = y0;
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case BR_TL:
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.right;           y0 = r.bottom;
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.left;    y1 = level * r.top;
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case BOTTOM_TOP:
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.left;            y0 = r.bottom;
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = x0;                y1 = level * r.top;
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case BL_TR:
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.left;            y0 = r.bottom;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.right;   y1 = level * r.top;
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case LEFT_RIGHT:
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.left;            y0 = r.top;
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.right;   y1 = y0;
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    default:/* TL_BR */
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x0 = r.left;            y0 = r.top;
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x1 = level * r.right;   y1 = level * r.bottom;
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,
943e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                            gradientColors, st.mPositions, Shader.TileMode.CLAMP));
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (st.mGradient == RADIAL_GRADIENT) {
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    x0 = r.left + (r.right - r.left) * st.mCenterX;
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    y0 = r.top + (r.bottom - r.top) * st.mCenterY;
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
948861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    float radius = st.mGradientRadius;
949b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette                    if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
950b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        // Fall back to parent width or height if intrinsic
951b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        // size is not specified.
952b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        final float width = st.mWidth >= 0 ? st.mWidth : r.width();
953b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        final float height = st.mHeight >= 0 ? st.mHeight : r.height();
954b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        radius *= Math.min(width, height);
955b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette                    } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
956861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                        radius *= Math.min(r.width(), r.height());
957861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    }
958b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
959861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    if (st.mUseLevel) {
960861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                        radius *= getLevel() / 10000.0f;
961861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    }
962b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
963861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    mGradientRadius = radius;
964b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
965b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                    if (radius <= 0) {
966b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        // We can't have a shader with non-positive radius, so
967b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette                        // let's have a very, very small radius.
968b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette                        radius = 0.001f;
969b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette                    }
970b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette
971861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette                    mFillPaint.setShader(new RadialGradient(
972e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                            x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP));
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (st.mGradient == SWEEP_GRADIENT) {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    x0 = r.left + (r.right - r.left) * st.mCenterX;
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    y0 = r.top + (r.bottom - r.top) * st.mCenterY;
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
977e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    int[] tempColors = gradientColors;
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    float[] tempPositions = null;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (st.mUseLevel) {
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tempColors = st.mTempColors;
982e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                        final int length = gradientColors.length;
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (tempColors == null || tempColors.length != length + 1) {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            tempColors = st.mTempColors = new int[length + 1];
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
986e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                        System.arraycopy(gradientColors, 0, tempColors, 0, length);
987e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                        tempColors[length] = gradientColors[length - 1];
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tempPositions = st.mTempPositions;
99052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        final float fraction = 1.0f / (length - 1);
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (tempPositions == null || tempPositions.length != length + 1) {
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            tempPositions = st.mTempPositions = new float[length + 1];
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        final float level = getLevel() / 10000.0f;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        for (int i = 0; i < length; i++) {
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            tempPositions[i] = i * fraction * level;
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tempPositions[length] = 1.0f;
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions));
10034d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette                }
10044d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette
10054d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette                // If we don't have a solid color, the alpha channel must be
10064d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette                // maxed out so that alpha modulation works correctly.
1007e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                if (st.mSolidColors == null) {
10084d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette                    mFillPaint.setColor(Color.BLACK);
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return !mRect.isEmpty();
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
101652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
101852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawable);
101952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.inflateWithAttributes(r, parser, a, R.styleable.GradientDrawable_visible);
102017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        updateStateFromTypedArray(a);
102152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        a.recycle();
102252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
102352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        inflateChildElements(r, parser, attrs, theme);
102452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
102545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        updateLocalState(r);
102652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
102752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
102852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
102952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void applyTheme(Theme t) {
103052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.applyTheme(t);
103152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
103252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final GradientState state = mGradientState;
103317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette        if (state == null) {
103417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            return;
103552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
103652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
103717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette        if (state.mThemeAttrs != null) {
103817cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette            final TypedArray a = t.resolveAttributes(
103917cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette                    state.mThemeAttrs, R.styleable.GradientDrawable);
104017cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette            updateStateFromTypedArray(a);
104117cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette            a.recycle();
104217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette        }
104352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
104445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        if (state.mTint != null && state.mTint.canApplyTheme()) {
1045e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            state.mTint = state.mTint.obtainForTheme(t);
104645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        }
104745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette
1048e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) {
1049e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            state.mSolidColors = state.mSolidColors.obtainForTheme(t);
105045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        }
105145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette
1052e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) {
1053e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            state.mStrokeColors = state.mStrokeColors.obtainForTheme(t);
105445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        }
105545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette
105617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        applyThemeChildElements(t);
105752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
105845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        updateLocalState(t.getResources());
105952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
106052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
106152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    /**
106252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * Updates the constant state from the values in the typed array.
106352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     */
106452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private void updateStateFromTypedArray(TypedArray a) {
106552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final GradientState state = mGradientState;
106652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
10678e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
10688e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChangingConfigurations |= a.getChangingConfigurations();
10698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
107017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        // Extract the theme attributes, if any.
107117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
107252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
107317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        state.mShape = a.getInt(R.styleable.GradientDrawable_shape, state.mShape);
107407c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette        state.mDither = a.getBoolean(R.styleable.GradientDrawable_dither, state.mDither);
107552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
107652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (state.mShape == RING) {
107717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            state.mInnerRadius = a.getDimensionPixelSize(
107817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    R.styleable.GradientDrawable_innerRadius, state.mInnerRadius);
107952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
108017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            if (state.mInnerRadius == -1) {
108152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                state.mInnerRadiusRatio = a.getFloat(
108217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                        R.styleable.GradientDrawable_innerRadiusRatio, state.mInnerRadiusRatio);
108352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
108452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
108517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            state.mThickness = a.getDimensionPixelSize(
108617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    R.styleable.GradientDrawable_thickness, state.mThickness);
108752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
108817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            if (state.mThickness == -1) {
108952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                state.mThicknessRatio = a.getFloat(
109017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                        R.styleable.GradientDrawable_thicknessRatio, state.mThicknessRatio);
109152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
109252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
109317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            state.mUseLevelForShape = a.getBoolean(
109417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape);
109552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
109643027b7bca554818cc4223389747d661819d5706Alan Viverette
109743027b7bca554818cc4223389747d661819d5706Alan Viverette        final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
109843027b7bca554818cc4223389747d661819d5706Alan Viverette        if (tintMode != -1) {
109943027b7bca554818cc4223389747d661819d5706Alan Viverette            state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN);
110043027b7bca554818cc4223389747d661819d5706Alan Viverette        }
110143027b7bca554818cc4223389747d661819d5706Alan Viverette
110243027b7bca554818cc4223389747d661819d5706Alan Viverette        final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
110343027b7bca554818cc4223389747d661819d5706Alan Viverette        if (tint != null) {
110443027b7bca554818cc4223389747d661819d5706Alan Viverette            state.mTint = tint;
110543027b7bca554818cc4223389747d661819d5706Alan Viverette        }
110687e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette
110787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        final int insetLeft = a.getDimensionPixelSize(
110887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette                R.styleable.GradientDrawable_opticalInsetLeft, state.mOpticalInsets.left);
110987e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        final int insetTop = a.getDimensionPixelSize(
111087e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette                R.styleable.GradientDrawable_opticalInsetTop, state.mOpticalInsets.top);
111187e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        final int insetRight = a.getDimensionPixelSize(
111287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette                R.styleable.GradientDrawable_opticalInsetRight, state.mOpticalInsets.right);
111387e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        final int insetBottom = a.getDimensionPixelSize(
111487e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette                R.styleable.GradientDrawable_opticalInsetBottom, state.mOpticalInsets.bottom);
111587e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        state.mOpticalInsets = Insets.of(insetLeft, insetTop, insetRight, insetBottom);
111652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
111752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
111852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
111952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public boolean canApplyTheme() {
1120d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette        return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme();
112152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
112252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
112352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private void applyThemeChildElements(Theme t) {
112417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final GradientState st = mGradientState;
112552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
112617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrSize != null) {
112717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
112817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrSize, R.styleable.GradientDrawableSize);
112917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            updateGradientDrawableSize(a);
113052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
113152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
113252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
113317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrGradient != null) {
113417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
113517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrGradient, R.styleable.GradientDrawableGradient);
113617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            try {
113717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawableGradient(t.getResources(), a);
113817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            } catch (XmlPullParserException e) {
113917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                throw new RuntimeException(e);
114017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            } finally {
114117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a.recycle();
114217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            }
114352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
114452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
114517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrSolid != null) {
114617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
114717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrSolid, R.styleable.GradientDrawableSolid);
114817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            updateGradientDrawableSolid(a);
114952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
115052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
115152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
115217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrStroke != null) {
115317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
115417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrStroke, R.styleable.GradientDrawableStroke);
115517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            updateGradientDrawableStroke(a);
115652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
115752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
115852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
115917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrCorners != null) {
116017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
116117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrCorners, R.styleable.DrawableCorners);
116217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            updateDrawableCorners(a);
116352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
116452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
116552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
116617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (st.mAttrPadding != null) {
116717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedArray a = t.resolveAttributes(
116817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    st.mAttrPadding, R.styleable.GradientDrawablePadding);
116917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            updateGradientDrawablePadding(a);
117052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
117152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
117252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
117352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
117452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
117552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            Theme theme) throws XmlPullParserException, IOException {
117652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        TypedArray a;
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179ed7894352f8addfe3d0da75cc7fe8bc6fef201dcRomain Guy        final int innerDepth = parser.getDepth() + 1;
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int depth;
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               && ((depth=parser.getDepth()) >= innerDepth
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       || type != XmlPullParser.END_TAG)) {
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type != XmlPullParser.START_TAG) {
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (depth > innerDepth) {
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
119152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String name = parser.getName();
119317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (name.equals("size")) {
119517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSize);
119617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawableSize(a);
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (name.equals("gradient")) {
119917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableGradient);
120017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawableGradient(r, a);
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (name.equals("solid")) {
120317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSolid);
120417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawableSolid(a);
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (name.equals("stroke")) {
120717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableStroke);
120817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawableStroke(a);
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (name.equals("corners")) {
121117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.DrawableCorners);
121217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateDrawableCorners(a);
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (name.equals("padding")) {
121517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawablePadding);
121617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                updateGradientDrawablePadding(a);
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.recycle();
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w("drawable", "Bad element under <shape>: " + name);
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
122152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
122252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
122352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
122417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateGradientDrawablePadding(TypedArray a) {
122517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final GradientState st = mGradientState;
122652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
12278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
12288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
12298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
123052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        // Extract the theme attributes, if any.
123117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mAttrPadding = a.extractThemeAttrs();
123217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1233982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette        if (st.mPadding == null) {
1234982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette            st.mPadding = new Rect();
1235982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette        }
1236982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette
123717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final Rect pad = st.mPadding;
123817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        pad.set(a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_left, pad.left),
123917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_top, pad.top),
124017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_right, pad.right),
124117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_bottom, pad.bottom));
124217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        mPadding = pad;
124352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
1244e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
124517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateDrawableCorners(TypedArray a) {
124617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final GradientState st = mGradientState;
124717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
12488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
12498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
12508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
125117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        // Extract the theme attributes, if any.
125217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mAttrCorners = a.extractThemeAttrs();
125317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
125417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final int radius = a.getDimensionPixelSize(
125517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                R.styleable.DrawableCorners_radius, (int) st.mRadius);
125652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        setCornerRadius(radius);
125717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
125817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        // TODO: Update these to be themeable.
125917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final int topLeftRadius = a.getDimensionPixelSize(
126052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.DrawableCorners_topLeftRadius, radius);
126117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final int topRightRadius = a.getDimensionPixelSize(
126252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.DrawableCorners_topRightRadius, radius);
126317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final int bottomLeftRadius = a.getDimensionPixelSize(
126452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.DrawableCorners_bottomLeftRadius, radius);
126517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final int bottomRightRadius = a.getDimensionPixelSize(
126652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.DrawableCorners_bottomRightRadius, radius);
126752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (topLeftRadius != radius || topRightRadius != radius ||
126852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                bottomLeftRadius != radius || bottomRightRadius != radius) {
126952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // The corner radii are specified in clockwise order (see Path.addRoundRect())
127052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            setCornerRadii(new float[] {
127152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    topLeftRadius, topLeftRadius,
127252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    topRightRadius, topRightRadius,
127352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    bottomRightRadius, bottomRightRadius,
127452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    bottomLeftRadius, bottomLeftRadius
127552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            });
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
127752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
127852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
127917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateGradientDrawableStroke(TypedArray a) {
128017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final GradientState st = mGradientState;
128117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
12828e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
12838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
12848e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
12858e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Extract the theme attributes, if any.
128617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mAttrStroke = a.extractThemeAttrs();
128717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
12883b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette        // We have an explicit stroke defined, so the default stroke width
12893b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette        // must be at least 0 or the current stroke width.
12903b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette        final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth);
129152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int width = a.getDimensionPixelSize(
12923b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                R.styleable.GradientDrawableStroke_width, defaultStrokeWidth);
129352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final float dashWidth = a.getDimension(
129417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth);
129517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
129617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        ColorStateList colorStateList = a.getColorStateList(
129717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                R.styleable.GradientDrawableStroke_color);
129817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (colorStateList == null) {
1299e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            colorStateList = st.mStrokeColors;
130017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        }
130117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
130252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (dashWidth != 0.0f) {
130352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final float dashGap = a.getDimension(
130417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                    R.styleable.GradientDrawableStroke_dashGap, st.mStrokeDashGap);
130552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            setStroke(width, colorStateList, dashWidth, dashGap);
130652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        } else {
130752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            setStroke(width, colorStateList);
130852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
130952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
131052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
131117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateGradientDrawableSolid(TypedArray a) {
13128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final GradientState st = mGradientState;
13138e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
13148e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
13158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
13168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
13178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Extract the theme attributes, if any.
13188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mAttrSolid = a.extractThemeAttrs();
131917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
132052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final ColorStateList colorStateList = a.getColorStateList(
132152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.GradientDrawableSolid_color);
132217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        if (colorStateList != null) {
132317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            setColor(colorStateList);
132417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        }
132552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
132652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
132717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateGradientDrawableGradient(Resources r, TypedArray a)
132852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            throws XmlPullParserException {
132952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final GradientState st = mGradientState;
133017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
13318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
13328e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
13338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
133417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        // Extract the theme attributes, if any.
133517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mAttrGradient = a.extractThemeAttrs();
133617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
133717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mCenterX = getFloatOrFraction(
133817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a, R.styleable.GradientDrawableGradient_centerX, st.mCenterX);
133917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mCenterY = getFloatOrFraction(
134017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                a, R.styleable.GradientDrawableGradient_centerY, st.mCenterY);
134117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mUseLevel = a.getBoolean(
134217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                R.styleable.GradientDrawableGradient_useLevel, st.mUseLevel);
134317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mGradient = a.getInt(
134417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                R.styleable.GradientDrawableGradient_type, st.mGradient);
134517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
134617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        // TODO: Update these to be themeable.
134752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int startColor = a.getColor(
134852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.GradientDrawableGradient_startColor, 0);
134952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final boolean hasCenterColor = a.hasValue(
135052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.GradientDrawableGradient_centerColor);
135152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int centerColor = a.getColor(
135252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.GradientDrawableGradient_centerColor, 0);
135352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int endColor = a.getColor(
135452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                R.styleable.GradientDrawableGradient_endColor, 0);
135552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
135652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (hasCenterColor) {
1357e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors = new int[3];
1358e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors[0] = startColor;
1359e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors[1] = centerColor;
1360e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors[2] = endColor;
136117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
136252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            st.mPositions = new float[3];
136352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            st.mPositions[0] = 0.0f;
136452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // Since 0.5f is default value, try to take the one that isn't 0.5f
136552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY;
136652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            st.mPositions[2] = 1f;
136752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        } else {
1368e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors = new int[2];
1369e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors[0] = startColor;
1370e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            st.mGradientColors[1] = endColor;
137152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
137252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
137352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (st.mGradient == LINEAR_GRADIENT) {
137417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
137552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            angle %= 360;
137652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
137752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            if (angle % 45 != 0) {
137852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                throw new XmlPullParserException(a.getPositionDescription()
137952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        + "<gradient> tag requires 'angle' attribute to "
138052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        + "be a multiple of 45");
138152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
138252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
138317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            st.mAngle = angle;
138417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
138552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            switch (angle) {
138652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 0:
138752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.LEFT_RIGHT;
138852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
138952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 45:
139052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.BL_TR;
139152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
139252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 90:
139352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.BOTTOM_TOP;
139452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
139552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 135:
139652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.BR_TL;
139752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
139852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 180:
139952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.RIGHT_LEFT;
140052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
140152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 225:
140252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.TR_BL;
140352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
140452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 270:
140552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.TOP_BOTTOM;
140652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
140752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                case 315:
140852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    st.mOrientation = Orientation.TL_BR;
140952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    break;
141052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
141152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        } else {
141217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
141352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            if (tv != null) {
141452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                final float radius;
141552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                final int radiusType;
141652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (tv.type == TypedValue.TYPE_FRACTION) {
141752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    radius = tv.getFraction(1.0f, 1.0f);
141852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
141952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
142052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                            & TypedValue.COMPLEX_UNIT_MASK;
142152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
142252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        radiusType = RADIUS_TYPE_FRACTION_PARENT;
142352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    } else {
142452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        radiusType = RADIUS_TYPE_FRACTION;
142552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    }
14262efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette                } else if (tv.type == TypedValue.TYPE_DIMENSION) {
142752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    radius = tv.getDimension(r.getDisplayMetrics());
142852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    radiusType = RADIUS_TYPE_PIXELS;
14292efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette                } else {
14302efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette                    radius = tv.getFloat();
14312efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette                    radiusType = RADIUS_TYPE_PIXELS;
143252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
143352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
143452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                st.mGradientRadius = radius;
143552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                st.mGradientRadiusType = radiusType;
143652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            } else if (st.mGradient == RADIAL_GRADIENT) {
143752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                throw new XmlPullParserException(
143852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        a.getPositionDescription()
143952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        + "<gradient> tag requires 'gradientRadius' "
144052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        + "attribute with radial type");
144152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
144252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
144352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
144452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
144517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette    private void updateGradientDrawableSize(TypedArray a) {
144617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        final GradientState st = mGradientState;
144752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
14488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
14498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChangingConfigurations |= a.getChangingConfigurations();
14508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
145152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        // Extract the theme attributes, if any.
145217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mAttrSize = a.extractThemeAttrs();
145317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
145417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mWidth = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_width, st.mWidth);
145517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        st.mHeight = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_height, st.mHeight);
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) {
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedValue tv = a.peekValue(index);
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float v = defaultValue;
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tv != null) {
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean vIsFraction = tv.type == TypedValue.TYPE_FRACTION;
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = vIsFraction ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return v;
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
146717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mGradientState.mWidth;
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mGradientState.mHeight;
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
147717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
147887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette    /** @hide */
147987e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette    @Override
148087e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette    public Insets getOpticalInsets() {
148187e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        return mGradientState.mOpticalInsets;
148287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette    }
148387e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
14866efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais        mGradientState.mChangingConfigurations = getChangingConfigurations();
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mGradientState;
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1490888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette    private boolean isOpaqueForState() {
1491888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        if (mGradientState.mStrokeWidth >= 0 && mStrokePaint != null
1492888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette                && !isOpaque(mStrokePaint.getColor())) {
1493888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette            return false;
1494888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        }
1495888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette
1496888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        if (!isOpaque(mFillPaint.getColor())) {
1497888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette            return false;
1498888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        }
1499888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette
1500888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        return true;
1501888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette    }
1502888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
150431ba192dd201df2cad96a8c503f730130ab0d80fChris Craik    public void getOutline(Outline outline) {
1505b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        final GradientState st = mGradientState;
1506b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        final Rect bounds = getBounds();
1507c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik        // only report non-zero alpha if shape being drawn is opaque
1508888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        outline.setAlpha(st.mOpaqueOverShape && isOpaqueForState() ? (mAlpha / 255.0f) : 0.0f);
1509b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
1510b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        switch (st.mShape) {
1511b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            case RECTANGLE:
1512b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                if (st.mRadiusArray != null) {
1513e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik                    buildPathIfDirty();
1514e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik                    outline.setConvexPath(mPath);
151531ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                    return;
1516b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                }
1517e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik
1518b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                float rad = 0;
1519b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                if (st.mRadius > 0.0f) {
1520b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                    // clamp the radius based on width & height, matching behavior in draw()
1521b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                    rad = Math.min(st.mRadius,
1522b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                            Math.min(bounds.width(), bounds.height()) * 0.5f);
1523b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                }
15247979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik                outline.setRoundRect(bounds, rad);
152531ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                return;
15267979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik            case OVAL:
15277979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik                outline.setOval(bounds);
152831ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                return;
15297979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik            case LINE:
15303b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                // Hairlines (0-width stroke) must have a non-empty outline for
15313b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                // shadows to draw correctly, so we'll use a very small width.
15323b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                final float halfStrokeWidth = mStrokePaint == null ?
15333b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                        0.0001f : mStrokePaint.getStrokeWidth() * 0.5f;
15343b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                final float centerY = bounds.centerY();
15353b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                final int top = (int) Math.floor(centerY - halfStrokeWidth);
15363b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette                final int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
1537b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
1538e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik                outline.setRect(bounds.left, top, bounds.right, bottom);
153931ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                return;
1540b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            default:
154131ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                // TODO: support more complex shapes
1542b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        }
1543b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
1544b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
1545b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    @Override
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGradientState = new GradientState(mGradientState);
154945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette            updateLocalState(null);
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1555727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette    /**
1556727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette     * @hide
1557727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette     */
1558727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette    public void clearMutated() {
1559727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette        super.clearMutated();
1560727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette        mMutated = false;
1561727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette    }
1562727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final static class GradientState extends ConstantState {
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mChangingConfigurations;
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mShape = RECTANGLE;
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mGradient = LINEAR_GRADIENT;
156771b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public int mAngle = 0;
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Orientation mOrientation;
1569e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public ColorStateList mSolidColors;
1570e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public ColorStateList mStrokeColors;
1571e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public int[] mGradientColors;
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int[] mTempColors; // no need to copy
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public float[] mTempPositions; // no need to copy
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public float[] mPositions;
157571b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public int mStrokeWidth = -1; // if >= 0 use stroking.
157671b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public float mStrokeDashWidth = 0.0f;
157771b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public float mStrokeDashGap = 0.0f;
157871b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public float mRadius = 0.0f; // use this if mRadiusArray is null
157971b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public float[] mRadiusArray = null;
158071b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette        public Rect mPadding = null;
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mWidth = -1;
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mHeight = -1;
158317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO;
158417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        public float mThicknessRatio = DEFAULT_THICKNESS_RATIO;
158517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        public int mInnerRadius = -1;
158617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette        public int mThickness = -1;
158707c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette        public boolean mDither = false;
158887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette        public Insets mOpticalInsets = Insets.NONE;
158907c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette
1590969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        float mCenterX = 0.5f;
1591969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        float mCenterY = 0.5f;
1592969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        float mGradientRadius = 0.5f;
1593969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        int mGradientRadiusType = RADIUS_TYPE_PIXELS;
1594969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        boolean mUseLevel = false;
1595969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        boolean mUseLevelForShape = true;
1596969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette
1597969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        boolean mOpaqueOverBounds;
1598969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette        boolean mOpaqueOverShape;
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
160043027b7bca554818cc4223389747d661819d5706Alan Viverette        ColorStateList mTint = null;
160143027b7bca554818cc4223389747d661819d5706Alan Viverette        PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
160243027b7bca554818cc4223389747d661819d5706Alan Viverette
160352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mThemeAttrs;
160452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrSize;
160552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrGradient;
160652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrSolid;
160752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrStroke;
160852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrCorners;
160952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mAttrPadding;
161052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
1611e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public GradientState(Orientation orientation, int[] gradientColors) {
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOrientation = orientation;
1613e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            setGradientColors(gradientColors);
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public GradientState(GradientState state) {
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mChangingConfigurations = state.mChangingConfigurations;
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShape = state.mShape;
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGradient = state.mGradient;
162017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette            mAngle = state.mAngle;
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOrientation = state.mOrientation;
1622e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mSolidColors = state.mSolidColors;
1623e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (state.mGradientColors != null) {
1624e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                mGradientColors = state.mGradientColors.clone();
1625562bf17c6c7c5226b2220e27a1543d4a43543d6cPhil Dubach            }
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state.mPositions != null) {
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPositions = state.mPositions.clone();
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1629e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mStrokeColors = state.mStrokeColors;
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokeWidth = state.mStrokeWidth;
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokeDashWidth = state.mStrokeDashWidth;
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokeDashGap = state.mStrokeDashGap;
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRadius = state.mRadius;
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state.mRadiusArray != null) {
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRadiusArray = state.mRadiusArray.clone();
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state.mPadding != null) {
1638982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette                mPadding = new Rect(state.mPadding);
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWidth = state.mWidth;
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeight = state.mHeight;
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInnerRadiusRatio = state.mInnerRadiusRatio;
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mThicknessRatio = state.mThicknessRatio;
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInnerRadius = state.mInnerRadius;
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mThickness = state.mThickness;
164607c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette            mDither = state.mDither;
164787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette            mOpticalInsets = state.mOpticalInsets;
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCenterX = state.mCenterX;
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCenterY = state.mCenterY;
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGradientRadius = state.mGradientRadius;
1651b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette            mGradientRadiusType = state.mGradientRadiusType;
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUseLevel = state.mUseLevel;
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUseLevelForShape = state.mUseLevelForShape;
1654c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            mOpaqueOverBounds = state.mOpaqueOverBounds;
1655c3a63c1fbb47f167f6736ad637fd6c6e3ee9d1d8Alan Viverette            mOpaqueOverShape = state.mOpaqueOverShape;
165643027b7bca554818cc4223389747d661819d5706Alan Viverette            mTint = state.mTint;
165743027b7bca554818cc4223389747d661819d5706Alan Viverette            mTintMode = state.mTintMode;
165852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mThemeAttrs = state.mThemeAttrs;
165952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrSize = state.mAttrSize;
166052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrGradient = state.mAttrGradient;
166152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrSolid = state.mAttrSolid;
166252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrStroke = state.mAttrStroke;
166352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrCorners = state.mAttrCorners;
166452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mAttrPadding = state.mAttrPadding;
166552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
166652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
166752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
166852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public boolean canApplyTheme() {
166945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette            return mThemeAttrs != null
167045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette                    || mAttrSize != null || mAttrGradient != null
167145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette                    || mAttrSolid != null || mAttrStroke != null
167245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette                    || mAttrCorners != null || mAttrPadding != null
167345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette                    || (mTint != null && mTint.canApplyTheme())
1674e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    || (mStrokeColors != null && mStrokeColors.canApplyTheme())
1675e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    || (mSolidColors != null && mSolidColors.canApplyTheme())
167645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette                    || super.canApplyTheme();
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable newDrawable() {
168145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette            return new GradientDrawable(this, null);
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
168317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1685c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        public Drawable newDrawable(Resources res) {
168645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette            return new GradientDrawable(this, res);
1687c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        }
168817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1689c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        @Override
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
1691e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            return mChangingConfigurations
1692e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0)
1693e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0)
1694e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    | (mTint != null ? mTint.getChangingConfigurations() : 0);
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setShape(int shape) {
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShape = shape;
1699e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy            computeOpacity();
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setGradientType(int gradient) {
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGradient = gradient;
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setGradientCenter(float x, float y) {
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCenterX = x;
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCenterY = y;
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1711e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public void setGradientColors(int[] colors) {
1712e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mGradientColors = colors;
1713e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mSolidColors = null;
1714e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy            computeOpacity();
17158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy        }
1716519494e207322581075c8ea884fde9d33bb9209eAlan Viverette
1717e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public void setSolidColors(ColorStateList colors) {
1718e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mGradientColors = null;
1719e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mSolidColors = colors;
1720e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy            computeOpacity();
1721e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy        }
1722e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
1723e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy        private void computeOpacity() {
1724c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            mOpaqueOverBounds = false;
1725c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            mOpaqueOverShape = false;
172639824f685c33f8aabbe9526b4cc79b7411e8b37fRaph Levien
1727e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (mGradientColors != null) {
1728e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                for (int i = 0; i < mGradientColors.length; i++) {
1729e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                    if (!isOpaque(mGradientColors[i])) {
1730e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy                        return;
1731e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy                    }
1732e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy                }
1733e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy            }
1734e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
173522cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase            // An unfilled shape is not opaque over bounds or shape
1736e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (mGradientColors == null && mSolidColors == null) {
173722cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase                return;
173822cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase            }
173922cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase
1740c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            // Colors are opaque, so opaqueOverShape=true,
1741c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            mOpaqueOverShape = true;
1742c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            // and opaqueOverBounds=true if shape fills bounds
1743c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik            mOpaqueOverBounds = mShape == RECTANGLE
1744c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik                    && mRadius <= 0
1745c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik                    && mRadiusArray == null;
1746e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy        }
1747e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
1748e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        public void setStroke(int width, ColorStateList colors, float dashWidth, float dashGap) {
1749a211dd28b93473c452d68432c602d5209b01c178Alan Viverette            mStrokeWidth = width;
1750e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            mStrokeColors = colors;
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokeDashWidth = dashWidth;
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokeDashGap = dashGap;
1753e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy            computeOpacity();
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setCornerRadius(float radius) {
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (radius < 0) {
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                radius = 0;
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRadius = radius;
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRadiusArray = null;
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1763e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setCornerRadii(float[] radii) {
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRadiusArray = radii;
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (radii == null) {
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRadius = 0;
17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1770e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setSize(int width, int height) {
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWidth = width;
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeight = height;
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1776861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette        public void setGradientRadius(float gradientRadius, int type) {
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGradientRadius = gradientRadius;
1778b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette            mGradientRadiusType = type;
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1782888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette    static boolean isOpaque(int color) {
1783888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette        return ((color >> 24) & 0xff) == 0xff;
1784888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette    }
1785888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette
178652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    /**
178752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * Creates a new themed GradientDrawable based on the specified constant state.
178852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * <p>
178952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * The resulting drawable is guaranteed to have a new constant state.
179052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     *
179152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * @param state Constant state from which the drawable inherits
179252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     */
179345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette    private GradientDrawable(GradientState state, Resources res) {
179417cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette        mGradientState = state;
179552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
179645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        updateLocalState(res);
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette    private void updateLocalState(Resources res) {
180045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        final GradientState state = mGradientState;
180145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette
1802e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        if (state.mSolidColors != null) {
1803519494e207322581075c8ea884fde9d33bb9209eAlan Viverette            final int[] currentState = getState();
1804e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            final int stateColor = state.mSolidColors.getColorForState(currentState, 0);
1805519494e207322581075c8ea884fde9d33bb9209eAlan Viverette            mFillPaint.setColor(stateColor);
1806e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette        } else if (state.mGradientColors == null) {
1807cf8675ee176a375f873792684d38a47f78348dffRomain Guy            // If we don't have a solid color and we don't have a gradient,
1808cf8675ee176a375f873792684d38a47f78348dffRomain Guy            // the app is stroking the shape, set the color to the default
1809cf8675ee176a375f873792684d38a47f78348dffRomain Guy            // value of state.mSolidColor
1810cf8675ee176a375f873792684d38a47f78348dffRomain Guy            mFillPaint.setColor(0);
18114d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette        } else {
18124d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette            // Otherwise, make sure the fill alpha is maxed out.
18134d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette            mFillPaint.setColor(Color.BLACK);
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
181517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPadding = state.mPadding;
181717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state.mStrokeWidth >= 0) {
18196a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokePaint.setStyle(Paint.Style.STROKE);
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStrokePaint.setStrokeWidth(state.mStrokeWidth);
182217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette
1823e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette            if (state.mStrokeColors != null) {
1824083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette                final int[] currentState = getState();
1825e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette                final int strokeStateColor = state.mStrokeColors.getColorForState(
1826083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette                        currentState, 0);
1827083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette                mStrokePaint.setColor(strokeStateColor);
1828083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette            }
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state.mStrokeDashWidth != 0.0f) {
183117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette                final DashPathEffect e = new DashPathEffect(
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0);
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStrokePaint.setPathEffect(e);
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18363ad771b384b55bc0b9ee9519f457ea7093bb0b74Alan Viverette
1837daec594370f0e47bf07d0c9c968e3c5dfedf0bb5Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
183845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        mGradientIsDirty = true;
183945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette
184045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette        state.computeOpacity();
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1843