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
19bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
2578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Bitmap;
2678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.BitmapFactory;
2778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas;
2878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter;
2978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.NinePatch;
3078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat;
3178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PorterDuff;
3278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PorterDuffColorFilter;
3378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Rect;
3478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Region;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
3611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackbornimport android.util.DisplayMetrics;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.StateSet;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue;
3978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.util.Xml;
4078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne
4178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport java.io.IOException;
4278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport java.io.InputStream;
43f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guyimport java.lang.ref.WeakReference;
4478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport java.util.Arrays;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Drawable is a general abstraction for "something that can be drawn."  Most
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often you will deal with Drawable as the type of resource retrieved for
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawing things to the screen; the Drawable class provides a generic API for
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * dealing with an underlying visual resource that may take a variety of forms.
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unlike a {@link android.view.View}, a Drawable does not have any facility to
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * receive events or otherwise interact with the user.
5323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In addition to simple drawing, Drawable provides a number of generic
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mechanisms for its client to interact with what is being drawn:
5623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> The {@link #setBounds} method <var>must</var> be called to tell the
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     Drawable where it is drawn and how large it should be.  All Drawables
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     should respect the requested size, often simply by scaling their
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     imagery.  A client can find the preferred size for some Drawables with
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     the {@link #getIntrinsicHeight} and {@link #getIntrinsicWidth} methods.
6323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> The {@link #getPadding} method can return from some Drawables
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     information about how to frame content that is placed inside of them.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     For example, a Drawable that is intended to be the frame for a button
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     widget would need to return padding that correctly places the label
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     inside of itself.
6923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> The {@link #setState} method allows the client to tell the Drawable
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     in which state it is to be drawn, such as "focused", "selected", etc.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     Some drawables may modify their imagery based on the selected state.
7323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> The {@link #setLevel} method allows the client to supply a single
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     continuous controller that can modify the Drawable is displayed, such as
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     a battery level or progress level.  Some drawables may modify their
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     imagery based on the current level.
7823bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> A Drawable can perform animations by calling back to its client
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     through the {@link Callback} interface.  All clients should support this
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     interface (via {@link #setCallback}) so that animations will work.  A
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     simple way to do this is through the system facilities such as
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link android.view.View#setBackgroundDrawable(Drawable)} and
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     {@link android.widget.ImageView}.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
8623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy *
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Though usually not visible to the application, Drawables may take a variety
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of forms:
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Bitmap</b>: the simplest Drawable, a PNG or JPEG image.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Nine Patch</b>: an extension to the PNG format allows it to
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     specify information about how to stretch it and place things inside of
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     it.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Shape</b>: contains simple drawing commands instead of a raw
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     bitmap, allowing it to resize better in some cases.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Layers</b>: a compound drawable, which draws multiple underlying
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     drawables on top of each other.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>States</b>: a compound drawable that selects one of a set of
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     drawables based on its state.
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Levels</b>: a compound drawable that selects one of a set of
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     drawables based on its level.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     <li> <b>Scale</b>: a compound drawable with a single child drawable,
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     whose overall size is modified based on the current level.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
10661fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez *
10761fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <div class="special reference">
10861fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <h3>Developer Guides</h3>
10961fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <p>For more information about how to use drawables, read the
11061fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and Drawables</a> developer
11161fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * guide. For information and examples of creating drawable resources (XML or bitmap files that
11261fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * can be loaded in code), read the
11361fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>
11461fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * document.</p></div>
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class Drawable {
11723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy    private static final Rect ZERO_BOUNDS_RECT = new Rect();
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mStateSet = StateSet.WILD_CARD;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLevel = 0;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mChangingConfigurations = 0;
1220f07b2c850ee1462ca4cf3137a954a9fc4bdf773Brad Fitzpatrick    private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
123f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    private WeakReference<Callback> mCallback = null;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mVisible = true;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio    private int mLayoutDirection;
127b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw in its bounds (set via setBounds) respecting optional effects such
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * as alpha (set via setAlpha) and color filter (set via setColorFilter).
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param canvas The canvas to draw into
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void draw(Canvas canvas);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify a bounding rectangle for the Drawable. This is where the drawable
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will draw when its draw() method is called.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBounds(int left, int top, int right, int bottom) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect oldBounds = mBounds;
14223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
14323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy        if (oldBounds == ZERO_BOUNDS_RECT) {
14423bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy            oldBounds = mBounds = new Rect();
14523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy        }
14623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (oldBounds.left != left || oldBounds.top != top ||
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                oldBounds.right != right || oldBounds.bottom != bottom) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBounds.set(left, top, right, bottom);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onBoundsChange(mBounds);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify a bounding rectangle for the Drawable. This is where the drawable
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will draw when its draw() method is called.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBounds(Rect bounds) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return a copy of the drawable's bounds in the specified Rect (allocated
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the caller). The bounds specify where this will draw when its draw()
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is called.
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bounds Rect to receive the drawable's bounds (allocated by the
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               caller).
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void copyBounds(Rect bounds) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bounds.set(mBounds);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return a copy of the drawable's bounds in a new Rect. This returns the
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same values as getBounds(), but the returned object is guaranteed to not
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be changed later by the drawable (i.e. it retains no reference to this
17823bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     * rect). If the caller already has a Rect allocated, call copyBounds(rect).
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A copy of the drawable's bounds
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Rect copyBounds() {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new Rect(mBounds);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the drawable's bounds Rect. Note: for efficiency, the returned
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * object may be the same object stored in the drawable (though this is not
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * guaranteed), so if a persistent copy of the bounds is needed, call
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * copyBounds(rect) instead.
19123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     * You should also not change the object returned by this method as it may
19223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     * be the same object stored in the drawable.
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The bounds of the drawable (which may change later, so caller
19523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *         beware). DO NOT ALTER the returned object as it may change the
19623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *         stored bounds of this drawable.
19723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
19823bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     * @see #copyBounds()
19923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     * @see #copyBounds(android.graphics.Rect)
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Rect getBounds() {
20223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy        if (mBounds == ZERO_BOUNDS_RECT) {
20323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy            mBounds = new Rect();
20423bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy        }
20523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBounds;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a mask of the configuration parameters for which this drawable
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may change, requiring that it be re-created.
21223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param configs A mask of the changing configuration parameters, as
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * defined by {@link android.content.res.Configuration}.
21523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.content.res.Configuration
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChangingConfigurations(int configs) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChangingConfigurations = configs;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return a mask of the configuration parameters for which this drawable
22469ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick     * may change, requiring that it be re-created.  The default implementation
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns whatever was provided through
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setChangingConfigurations(int)} or 0 by default.  Subclasses
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may extend this to or in the changing configurations of any other
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawables they hold.
22923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a mask of the changing configuration parameters, as
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * defined by {@link android.content.res.Configuration}.
23223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.content.res.Configuration
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mChangingConfigurations;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23823bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set to true to have the drawable dither its colors when drawn to a device
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with fewer than 8-bits per color component. This can improve the look on
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * those devices, but can also slow down the drawing a little.
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {}
24523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set to true to have the drawable filter its bitmap when scaled or rotated
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (for drawables that use bitmaps). If the drawable does not use bitmaps,
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this call is ignored. This can improve the look when scaled or rotated,
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but also slows down the drawing.
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFilterBitmap(boolean filter) {}
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this interface if you want to create an animated drawable that
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extends {@link android.graphics.drawable.Drawable Drawable}.
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Upon retrieving a drawable, use
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setCallback(android.graphics.drawable.Drawable.Callback)}
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to supply your implementation of the interface to the drawable; it uses
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this interface to schedule and execute animation changes.
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static interface Callback {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when the drawable needs to be redrawn.  A view at this point
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * should invalidate itself (or at least the part of itself where the
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * drawable appears).
26723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy         *
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param who The drawable that is requesting the update.
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void invalidateDrawable(Drawable who);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * A Drawable can call this to schedule the next frame of its
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * animation.  An implementation can generally simply call
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link android.os.Handler#postAtTime(Runnable, Object, long)} with
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the parameters <var>(what, who, when)</var> to perform the
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * scheduling.
27823bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy         *
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param who The drawable being scheduled.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param what The action to execute.
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param when The time (in milliseconds) to run.  The timebase is
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *             {@link android.os.SystemClock#uptimeMillis}
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void scheduleDrawable(Drawable who, Runnable what, long when);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * A Drawable can call this to unschedule an action previously
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * scheduled with {@link #scheduleDrawable}.  An implementation can
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * generally simply call
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link android.os.Handler#removeCallbacks(Runnable, Object)} with
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the parameters <var>(what, who)</var> to unschedule the drawable.
29223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy         *
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param who The drawable being unscheduled.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param what The action being unscheduled.
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void unscheduleDrawable(Drawable who, Runnable what);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bind a {@link Callback} object to this Drawable.  Required for clients
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that want to support animated drawables.
30223bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cb The client's Callback implementation.
304f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     *
305f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * @see #getCallback()
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void setCallback(Callback cb) {
308f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        mCallback = new WeakReference<Callback>(cb);
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
312f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * Return the current {@link Callback} implementation attached to this
313f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * Drawable.
314f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     *
315f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * @return A {@link Callback} instance or null if no callback was set.
316f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     *
317f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * @see #setCallback(android.graphics.drawable.Drawable.Callback)
318f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     */
319f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    public Callback getCallback() {
320f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (mCallback != null) {
321f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            return mCallback.get();
322f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        }
323f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        return null;
324f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    }
325f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy
326f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    /**
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Use the current {@link Callback} implementation to have this Drawable
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * redrawn.  Does nothing if there is no Callback attached to the
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable.
33023bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see Callback#invalidateDrawable
332f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * @see #getCallback()
333f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy     * @see #setCallback(android.graphics.drawable.Drawable.Callback)
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
335f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    public void invalidateSelf() {
336f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
337f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
338f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.invalidateDrawable(this);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Use the current {@link Callback} implementation to have this Drawable
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * scheduled.  Does nothing if there is no Callback attached to the
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable.
34623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param what The action being scheduled.
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param when The time (in milliseconds) to run.
34923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see Callback#scheduleDrawable
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
352f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    public void scheduleSelf(Runnable what, long when) {
353f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
354f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
355f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.scheduleDrawable(this, what, when);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Use the current {@link Callback} implementation to have this Drawable
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * unscheduled.  Does nothing if there is no Callback attached to the
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable.
36323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param what The runnable that you no longer want called.
36523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see Callback#unscheduleDrawable
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
368f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy    public void unscheduleSelf(Runnable what) {
369f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
370f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
371f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.unscheduleDrawable(this, what);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
376b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     * Returns the resolved layout direction for this Drawable.
377b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     *
378c5daf84f6647d3280c59554cd6ec9c2a4f119bfcFabrice Di Meglio     * @return One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
379c5daf84f6647d3280c59554cd6ec9c2a4f119bfcFabrice Di Meglio     *   {@link android.view.View#LAYOUT_DIRECTION_RTL}
380f358260af4cd34961acc13d849819c8b6089f309Fabrice Di Meglio     *
381f358260af4cd34961acc13d849819c8b6089f309Fabrice Di Meglio     * @hide
382c1da65187a4b9de8f72bd617ef937030187c0a92Fabrice Di Meglio     */
383b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio    public int getLayoutDirection() {
384b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio        return mLayoutDirection;
385b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio    }
386b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio
387b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio    /**
388b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     * Set the layout direction for this drawable. Should be a resolved direction as the
389b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     * Drawable as no capacity to do the resolution on his own.
390b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     *
391c5daf84f6647d3280c59554cd6ec9c2a4f119bfcFabrice Di Meglio     * @param layoutDirection One of {@link android.view.View#LAYOUT_DIRECTION_LTR},
392f358260af4cd34961acc13d849819c8b6089f309Fabrice Di Meglio     *   {@link android.view.View#LAYOUT_DIRECTION_RTL}
393b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     *
394f358260af4cd34961acc13d849819c8b6089f309Fabrice Di Meglio     * @hide
395b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio     */
396b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio    public void setLayoutDirection(int layoutDirection) {
397b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio        if (getLayoutDirection() != layoutDirection) {
398b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio            mLayoutDirection = layoutDirection;
3996a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio        }
4006a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio    }
4016a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio
4026a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio    /**
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify an alpha value for the drawable. 0 means fully transparent, and
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 255 means fully opaque.
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void setAlpha(int alpha);
40723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify an optional colorFilter for the drawable. Pass null to remove
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * any filters.
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void setColorFilter(ColorFilter cf);
41323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify a color and porterduff mode to be the colorfilter for this
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawable.
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(int color, PorterDuff.Mode mode) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setColorFilter(new PorterDuffColorFilter(color, mode));
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
42123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearColorFilter() {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setColorFilter(null);
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether this view will change its appearance based on state.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Clients can use this to determine whether it is necessary to calculate
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their state and call setState.
43023bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this view changes its appearance based on state, false
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         otherwise.
43323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setState(int[])
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
43923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify a set of states for the drawable. These are use-case specific,
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * so see the relevant documentation. As an example, the background for
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * widgets like Button understand the following states:
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * [{@link android.R.attr#state_focused},
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  {@link android.R.attr#state_pressed}].
44623bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the new state you are supplying causes the appearance of the
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable to change, then it is responsible for calling
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * true will be returned from this function.
45123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note: The Drawable holds a reference on to <var>stateSet</var>
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * until a new state array is given to it, so you must not modify this
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * array during that time.</p>
45523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stateSet The new set of states to be displayed.
45723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if this change in state has caused the appearance
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the Drawable to change (hence requiring an invalidate), otherwise
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns false.
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setState(final int[] stateSet) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!Arrays.equals(mStateSet, stateSet)) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStateSet = stateSet;
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return onStateChange(stateSet);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Describes the current state, as a union of primitve states, such as
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.attr#state_focused},
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.attr#state_selected}, etc.
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Some drawables may modify their imagery based on the selected state.
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return An array of resource Ids describing the current state.
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int[] getState() {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mStateSet;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
48023bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
482079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * If this Drawable does transition animations between states, ask that
483079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * it immediately jump to the current state and skip any active animations.
484079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
485079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void jumpToCurrentState() {
486079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
487079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
488079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current drawable that will be used by this drawable. For simple drawables, this
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         is just the drawable itself. For drawables that change state like
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link StateListDrawable} and {@link LevelListDrawable} this will be the child drawable
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         currently in use.
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getCurrent() {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specify the level for the drawable.  This allows a drawable to vary its
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * imagery based on a continuous controller, for example to show progress
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or volume level.
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the new level you are supplying causes the appearance of the
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable to change, then it is responsible for calling
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * true will be returned from this function.
50723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param level The new level, from 0 (minimum) to 10000 (maximum).
50923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if this change in level has caused the appearance
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the Drawable to change (hence requiring an invalidate), otherwise
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns false.
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean setLevel(int level) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLevel != level) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLevel = level;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return onLevelChange(level);
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the current level.
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return int Current level, from 0 (minimum) to 10000 (maximum).
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getLevel() {
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLevel;
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set whether this Drawable is visible.  This generally does not impact
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the Drawable's behavior, but is a hint that can be used by some
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawables, for example, to decide whether run animations.
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param visible Set to true if visible, false if not.
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restart You can supply true here to force the drawable to behave
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                as if it has just become visible, even if it had last
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                been set visible.  Used for example to force animations
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                to restart.
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return boolean Returns true if the new visibility is different than
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         its previous state.
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = mVisible != visible;
5479891e1fce5f29d0421d34aa481037417bd70853dChet Haase        if (changed) {
5489891e1fce5f29d0421d34aa481037417bd70853dChet Haase            mVisible = visible;
5499891e1fce5f29d0421d34aa481037417bd70853dChet Haase            invalidateSelf();
5509891e1fce5f29d0421d34aa481037417bd70853dChet Haase        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isVisible() {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mVisible;
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the opacity/transparency of this Drawable.  The returned value is
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * one of the abstract format constants in
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.graphics.PixelFormat}:
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.graphics.PixelFormat#UNKNOWN},
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.graphics.PixelFormat#TRANSLUCENT},
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.graphics.PixelFormat#TRANSPARENT}, or
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.graphics.PixelFormat#OPAQUE}.
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generally a Drawable should be as conservative as possible with the
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * value it returns.  For example, if it contains multiple child drawables
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and only shows one of them at a time, if only one of the children is
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * TRANSLUCENT and the others are OPAQUE then TRANSLUCENT should be
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returned.  You can use the method {@link #resolveOpacity} to perform a
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * standard reduction of two opacities to the appropriate single output.
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note that the returned value does <em>not</em> take into account a
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * custom alpha or color filter that has been applied by the client through
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #setAlpha} or {@link #setColorFilter} methods.
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return int The opacity class of the Drawable.
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.graphics.PixelFormat
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int getOpacity();
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the appropriate opacity value for two source opacities.  If
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * either is UNKNOWN, that is returned; else, if either is TRANSLUCENT,
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that is returned; else, if either is TRANSPARENT, that is returned;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * else, OPAQUE is returned.
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>This is to help in implementing {@link #getOpacity}.
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op1 One opacity value.
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op2 Another opacity value.
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return int The combined opacity value.
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getOpacity
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static int resolveOpacity(int op1, int op2) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (op1 == op2) {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op1;
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (op1 == PixelFormat.UNKNOWN || op2 == PixelFormat.UNKNOWN) {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PixelFormat.UNKNOWN;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (op1 == PixelFormat.TRANSLUCENT || op2 == PixelFormat.TRANSLUCENT) {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PixelFormat.TRANSLUCENT;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (op1 == PixelFormat.TRANSPARENT || op2 == PixelFormat.TRANSPARENT) {
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return PixelFormat.TRANSPARENT;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PixelFormat.OPAQUE;
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a Region representing the part of the Drawable that is completely
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * transparent.  This can be used to perform drawing operations, identifying
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * which parts of the target will not change when rendering the Drawable.
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation returns null, indicating no transparent
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * region; subclasses can optionally override this to return an actual
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Region if they want to supply this optimization information, but it is
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not required that they do so.
62323bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns null if the Drawables has no transparent region to
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * report, else a Region holding the parts of the Drawable's bounds that
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are transparent.
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Region getTransparentRegion() {
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
63123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this in your subclass to change appearance if you recognize the
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified state.
63523bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if the state change has caused the appearance of
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the Drawable to change (that is, it needs to be drawn), else false
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it looks the same and there is no need to redraw it since its
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * last state.
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) { return false; }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Override this in your subclass to change appearance if you vary based
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  on level.
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if the level change has caused the appearance of
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the Drawable to change (that is, it needs to be drawn), else false
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it looks the same and there is no need to redraw it since its
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * last level.
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) { return false; }
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this in your subclass to change appearance if you recognize the
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified state.
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {}
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the intrinsic width of the underlying drawable object.  Returns
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -1 if it has no intrinsic width, such as with a solid color.
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the intrinsic height of the underlying drawable object. Returns
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -1 if it has no intrinsic height, such as with a solid color.
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
67123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the minimum width suggested by this Drawable. If a View uses this
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable as a background, it is suggested that the View use at least this
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * value for its width. (There will be some scenarios where this will not be
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * possible.) This value should INCLUDE any padding.
67723bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The minimum width suggested by this Drawable. If this Drawable
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         doesn't have a suggested minimum width, 0 is returned.
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumWidth() {
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int intrinsicWidth = getIntrinsicWidth();
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return intrinsicWidth > 0 ? intrinsicWidth : 0;
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the minimum height suggested by this Drawable. If a View uses this
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Drawable as a background, it is suggested that the View use at least this
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * value for its height. (There will be some scenarios where this will not be
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * possible.) This value should INCLUDE any padding.
69123bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy     *
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The minimum height suggested by this Drawable. If this Drawable
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         doesn't have a suggested minimum height, 0 is returned.
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumHeight() {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int intrinsicHeight = getIntrinsicHeight();
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return intrinsicHeight > 0 ? intrinsicHeight : 0;
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
69923bd84ce6c448b73847eb404f3a1cc7b10afb6d6Romain Guy
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return in padding the insets suggested by this Drawable for placing
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * content inside the drawable's bounds. Positive values move toward the
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * center of the Drawable (set Rect.inset). Returns true if this drawable
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * actually has a padding, else false. When false is returned, the padding
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is always set to 0.
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.set(0, 0, 0, 0);
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7131557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * Return in insets the layout insets suggested by this Drawable for use with alignment
714bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milne     * operations during layout.
7151557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     *
7161557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * @hide
7171557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
718bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milne    public Insets getLayoutInsets() {
719bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milne        return Insets.NONE;
7201557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
7211557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
7221557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Make this drawable mutable. This operation cannot be reversed. A mutable
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawable is guaranteed to not share its state with any other drawable.
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is especially useful when you need to modify properties of drawables
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * loaded from resources. By default, all drawables instances loaded from
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same resource share a common state; if you modify the state of one
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * instance, all the other instances will receive the same modification.
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Calling this method on a mutable Drawable will have no effect.
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This drawable.
7331e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @see ConstantState
7341e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @see #getConstantState()
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a drawable from an inputstream
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Drawable createFromStream(InputStream is, String srcName) {
74446407d831ef31c0935e6d069198ffb275c840d83Dianne Hackborn        return createFromResourceStream(null, null, is, srcName, null);
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
74811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Create a drawable from an inputstream, using the given resources and
74911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * value to determine density information.
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Drawable createFromResourceStream(Resources res, TypedValue value,
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputStream is, String srcName) {
75346407d831ef31c0935e6d069198ffb275c840d83Dianne Hackborn        return createFromResourceStream(res, value, is, srcName, null);
7547341d7a104b47996445d069a695e155a07184606Dianne Hackborn    }
7557341d7a104b47996445d069a695e155a07184606Dianne Hackborn
7567341d7a104b47996445d069a695e155a07184606Dianne Hackborn    /**
7577341d7a104b47996445d069a695e155a07184606Dianne Hackborn     * Create a drawable from an inputstream, using the given resources and
7587341d7a104b47996445d069a695e155a07184606Dianne Hackborn     * value to determine density information.
7597341d7a104b47996445d069a695e155a07184606Dianne Hackborn     */
7607341d7a104b47996445d069a695e155a07184606Dianne Hackborn    public static Drawable createFromResourceStream(Resources res, TypedValue value,
7617341d7a104b47996445d069a695e155a07184606Dianne Hackborn            InputStream is, String srcName, BitmapFactory.Options opts) {
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (is == null) {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*  ugh. The decodeStream contract is that we have already allocated
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            the pad rect, but if the bitmap does not had a ninepatch chunk,
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            then the pad will be ignored. If we could change this to lazily
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            alloc/assign the rect, we could avoid the GC churn of making new
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rects only to drop them on the floor.
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect pad = new Rect();
77411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
77511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // Special stuff for compatibility mode: if the target density is not
77611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // the same as the display density, but the resource -is- the same as
77711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // the display density, then don't scale it down to the target density.
77811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // This allows us to load the system's density-correct resources into
77911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // an application in compatibility mode, without scaling those down
78011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // to the compatibility density only to have them scaled back up when
78111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // drawn to the screen.
7827341d7a104b47996445d069a695e155a07184606Dianne Hackborn        if (opts == null) opts = new BitmapFactory.Options();
783f1c0aeda259dd0dbab4356c909d33fe7e1ca0d2aDianne Hackborn        opts.inScreenDensity = res != null
784f1c0aeda259dd0dbab4356c909d33fe7e1ca0d2aDianne Hackborn                ? res.getDisplayMetrics().noncompatDensityDpi : DisplayMetrics.DENSITY_DEVICE;
78511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        Bitmap  bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bm != null) {
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] np = bm.getNinePatchChunk();
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (np == null || !NinePatch.isNinePatchChunk(np)) {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                np = null;
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pad = null;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
792ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            int[] layoutBounds = bm.getLayoutBounds();
793ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            Rect layoutBoundsRect = null;
794ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            if (layoutBounds != null) {
795ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani                layoutBoundsRect = new Rect(layoutBounds[0], layoutBounds[1],
796ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani                                             layoutBounds[2], layoutBounds[3]);
797ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            }
798ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            return drawableFromBitmap(res, bm, np, pad, layoutBoundsRect, srcName);
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a drawable from an XML document. For more information on how to
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * create resources in XML, see
806dfe5c204403bc56c29bb36410574eab8b1950417Scott Main     * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Drawable createFromXml(Resources r, XmlPullParser parser)
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AttributeSet attrs = Xml.asAttributeSet(parser);
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while ((type=parser.next()) != XmlPullParser.START_TAG &&
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                type != XmlPullParser.END_DOCUMENT) {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty loop
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (type != XmlPullParser.START_TAG) {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("No start tag found");
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Drawable drawable = createFromXmlInner(r, parser, attrs);
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (drawable == null) {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Unknown initial tag: " + parser.getName());
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return drawable;
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create from inside an XML document.  Called on a parser positioned at
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a tag in an XML document, tries to create a Drawable from that tag.
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if the tag is not a valid drawable.
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs)
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    throws XmlPullParserException, IOException {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Drawable drawable;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final String name = parser.getName();
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (name.equals("selector")) {
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new StateListDrawable();
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("level-list")) {
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new LevelListDrawable();
8468c7a580b34d67fefd5f777c7bd6247b2d3960608Dianne Hackborn        /* Probably not doing this.
84778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne        } else if (name.equals("mipmap")) {
84878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne            drawable = new MipmapDrawable();
8498c7a580b34d67fefd5f777c7bd6247b2d3960608Dianne Hackborn        */
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("layer-list")) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new LayerDrawable();
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("transition")) {
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new TransitionDrawable();
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("color")) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new ColorDrawable();
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("shape")) {
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new GradientDrawable();
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("scale")) {
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new ScaleDrawable();
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("clip")) {
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new ClipDrawable();
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("rotate")) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new RotateDrawable();
864f4f7046183f0daedd17703fa16cf9026442bdaeeRomain Guy        } else if (name.equals("animated-rotate")) {
865f4f7046183f0daedd17703fa16cf9026442bdaeeRomain Guy            drawable = new AnimatedRotateDrawable();
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("animation-list")) {
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new AnimationDrawable();
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("inset")) {
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new InsetDrawable();
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("bitmap")) {
87178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne            drawable = new BitmapDrawable(r);
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (r != null) {
87311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn               ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (name.equals("nine-patch")) {
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = new NinePatchDrawable();
87711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            if (r != null) {
87811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn                ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
87911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn             }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException(parser.getPositionDescription() +
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ": invalid drawable tag " + name);
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawable.inflate(r, parser, attrs);
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return drawable;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a drawable from file path name.
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Drawable createFromPath(String pathName) {
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pathName == null) {
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = BitmapFactory.decodeFile(pathName);
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bm != null) {
900ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            return drawableFromBitmap(null, bm, null, null, null, pathName);
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9061e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne    /**
9071e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * Inflate this Drawable from an XML resource.
9081e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     */
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.Drawable);
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflateWithAttributes(r, parser, a, com.android.internal.R.styleable.Drawable_visible);
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9171e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne    /**
9181e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * Inflate a Drawable from an XML resource.
9191e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     *
9201e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @throws XmlPullParserException
9211e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @throws IOException
9221e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     */
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void inflateWithAttributes(Resources r, XmlPullParser parser,
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TypedArray attrs, int visibleAttr)
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mVisible = attrs.getBoolean(visibleAttr, mVisible);
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9301e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne    /**
9311e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * This abstract class is used by {@link Drawable}s to store shared constant state and data
9321e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * between Drawables. {@link BitmapDrawable}s created from the same resource will for instance
9331e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * share a unique bitmap stored in their ConstantState.
9341e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     *
9351e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * <p>
9361e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * {@link #newDrawable(Resources)} can be used as a factory to create new Drawable instances
9371e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * from this ConstantState.
9381e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * </p>
9391e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     *
9401e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * Use {@link Drawable#getConstantState()} to retrieve the ConstantState of a Drawable. Calling
9411e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * {@link Drawable#mutate()} on a Drawable should typically create a new ConstantState for that
9421e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * Drawable.
9431e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     */
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static abstract class ConstantState {
945c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        /**
946c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * Create a new drawable without supplying resources the caller
947c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * is running in.  Note that using this means the density-dependent
948c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * drawables (like bitmaps) will not be able to update their target
94920fc9bfe3ad16c5f36026fc43c85d0647b75cc40Gilles Debunne         * density correctly. One should use {@link #newDrawable(Resources)}
95020fc9bfe3ad16c5f36026fc43c85d0647b75cc40Gilles Debunne         * instead to provide a resource.
951c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         */
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public abstract Drawable newDrawable();
953c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        /**
954c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * Create a new Drawable instance from its constant state.  This
955c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * must be implemented for drawables that change based on the target
956c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * density of their caller (that is depending on whether it is
957c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * in compatibility mode).
958c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         */
959c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        public Drawable newDrawable(Resources res) {
960c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn            return newDrawable();
961c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        }
962c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        /**
963c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * Return a bit mask of configuration changes that will impact
964c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         * this drawable (and thus require completely reloading it).
965c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn         */
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public abstract int getChangingConfigurations();
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9691e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne    /**
9701e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * Return a {@link ConstantState} instance that holds the shared state of this Drawable.
9711e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     *q
9721e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @return The ConstantState associated to that Drawable.
9731e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @see ConstantState
9741e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     * @see Drawable#mutate()
9751e91b3fde0a1a76388c7f2a7fd67562c66818f2eGilles Debunne     */
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Drawable drawableFromBitmap(Resources res, Bitmap bm, byte[] np,
981ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            Rect pad, Rect layoutBounds, String srcName) {
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (np != null) {
9841557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne            return new NinePatchDrawable(res, bm, np, pad, layoutBounds, srcName);
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return new BitmapDrawable(res, bm);
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
991