BitmapDrawable.java revision b1af7f3d4be6cd6bc6e1e805f22c209e19bf928f
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 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.BitmapFactory; 23b1216dd916e0f5fdec29684120c5bcc904800916Romain Guyimport android.graphics.BitmapShader; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Shader; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.DisplayMetrics; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * BitmapDrawable from a file path, an input stream, through XML inflation, or from 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link android.graphics.Bitmap} object. 42dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code><bitmap></code> element. For more 43dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a 44dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p> 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also see the {@link android.graphics.Bitmap} class, which handles the management and 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transformation of raw bitmap graphics, and should be used when drawing to a 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.graphics.Canvas}. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_src 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_antialias 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_filter 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_dither 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_gravity 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_tileMode 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BitmapDrawable extends Drawable { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed private static final int DEFAULT_PAINT_FLAGS = 61211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private BitmapState mBitmapState; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bitmap mBitmap; 64c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn private int mTargetDensity; 65c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mDstRect = new Rect(); // Gravity.apply() sets this 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mApplyGravity; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 7011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 71c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn // These are scaled to match the target density. 7211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private int mBitmapWidth; 7311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private int mBitmapHeight; 7411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 7511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 7611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create an empty drawable, not dealing with density. 777ac40e38696aa74d7b7938add8fdbc47180ae424Romain Guy * @deprecated Use {@link #BitmapDrawable(android.content.res.Resources, android.graphics.Bitmap)} 787ac40e38696aa74d7b7938add8fdbc47180ae424Romain Guy * instead to specify a bitmap to draw with and ensure the correct density is set. 7911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 804a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable() { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = new BitmapState((Bitmap) null); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 8611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create an empty drawable, setting initial target density based on 8711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * the display metrics of the resources. 887ac40e38696aa74d7b7938add8fdbc47180ae424Romain Guy * @deprecated Use {@link #BitmapDrawable(android.content.res.Resources, android.graphics.Bitmap)} 897ac40e38696aa74d7b7938add8fdbc47180ae424Romain Guy * instead to specify a bitmap to draw with. 9011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 917ac40e38696aa74d7b7938add8fdbc47180ae424Romain Guy @Deprecated 92ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 9311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public BitmapDrawable(Resources res) { 9411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapState = new BitmapState((Bitmap) null); 95c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 9611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 9711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 9811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 9911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create drawable from a bitmap, not dealing with density. 10011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure 10111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * that the drawable has correctly set its target density. 10211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 1034a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(Bitmap bitmap) { 105c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(bitmap), null); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 10911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create drawable from a bitmap, setting initial target density based on 11011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * the display metrics of the resources. 11111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 11211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public BitmapDrawable(Resources res, Bitmap bitmap) { 113c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(bitmap), res); 114c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 11511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 11611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 117c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 118c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by opening a given file path and decoding the bitmap. 119c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, String)} to ensure 120c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * that the drawable has correctly set its target density. 121c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 12229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn @Deprecated 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(String filepath) { 124c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); 125c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (mBitmap == null) { 126c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); 127c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 128c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 129c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 130c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 131c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by opening a given file path and decoding the bitmap. 132c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 133ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 134c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public BitmapDrawable(Resources res, String filepath) { 135c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); 136c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmap == null) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 142c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 143c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by decoding a bitmap from the given input stream. 144c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, java.io.InputStream)} to ensure 145c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * that the drawable has correctly set its target density. 146c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 14729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn @Deprecated 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(java.io.InputStream is) { 149c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeStream(is)), null); 150c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (mBitmap == null) { 151c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); 152c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 153c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 154c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 155c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 156c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by decoding a bitmap from the given input stream. 157c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 158ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 159c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public BitmapDrawable(Resources res, java.io.InputStream is) { 160c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeStream(is)), null); 161c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmap == null) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 167ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 168ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Returns the paint used to render this drawable. 169ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Paint getPaint() { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mPaint; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 173ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy 174ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 175ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Returns the bitmap used by this drawable to render. May be null. 176ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Bitmap getBitmap() { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmap; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private void computeBitmapSize() { 18211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity); 18311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity); 18411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 18511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setBitmap(Bitmap bitmap) { 1879891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (bitmap != mBitmap) { 1889891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmap = bitmap; 1899891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (bitmap != null) { 1909891e1fce5f29d0421d34aa481037417bd70853dChet Haase computeBitmapSize(); 1919891e1fce5f29d0421d34aa481037417bd70853dChet Haase } else { 1929891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmapWidth = mBitmapHeight = -1; 1939891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 1949891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the density scale at which this drawable will be rendered. This 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method assumes the drawable will be rendered at the same density as the 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified canvas. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param canvas The Canvas from which the density scale must be obtained. 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 20611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(Canvas canvas) { 20911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn setTargetDensity(canvas.getDensity()); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the density scale at which this drawable will be rendered. 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param metrics The DisplayMetrics indicating the density scale for this drawable. 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 21711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 21811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(DisplayMetrics metrics) { 2219891e1fce5f29d0421d34aa481037417bd70853dChet Haase setTargetDensity(metrics.densityDpi); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Set the density at which this drawable will be rendered. 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param density The density scale for this drawable. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 22911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 23011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(int density) { 2339891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mTargetDensity != density) { 2349891e1fce5f29d0421d34aa481037417bd70853dChet Haase mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density; 2359891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mBitmap != null) { 2369891e1fce5f29d0421d34aa481037417bd70853dChet Haase computeBitmapSize(); 2379891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 2389891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 23911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Get the gravity used to position/stretch the bitmap within its bounds. 24311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * See android.view.Gravity 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the gravity applied to the bitmap 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getGravity() { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mGravity; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2495769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Set the gravity used to position/stretch the bitmap within its bounds. 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project See android.view.Gravity 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 2559891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mBitmapState.mGravity != gravity) { 2569891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmapState.mGravity = gravity; 2579891e1fce5f29d0421d34aa481037417bd70853dChet Haase mApplyGravity = true; 2589891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2599891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 262ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 2635769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * Enables or disables the mipmap hint for this drawable's bitmap. 2645769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * See {@link Bitmap#setHasMipMap(boolean)} for more information. 2655769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2665769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * If the bitmap is null calling this method has no effect. 2675769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2685769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @param mipMap True if the bitmap should use mipmaps, false otherwise. 2695769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2705769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @see #hasMipMap() 2715769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy */ 2725769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy public void setMipMap(boolean mipMap) { 2735769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy if (mBitmapState.mBitmap != null) { 2745769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy mBitmapState.mBitmap.setHasMipMap(mipMap); 2755769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy invalidateSelf(); 2765769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy } 2775769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy } 2785769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy 2795769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy /** 2805769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * Indicates whether the mipmap hint is enabled on this drawable's bitmap. 2815769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2825769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @return True if the mipmap hint is set, false otherwise. If the bitmap 2835769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * is null, this method always returns false. 2845769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2855769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @see #setMipMap(boolean) 2865769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy */ 2875769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy public boolean hasMipMap() { 2885769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy return mBitmapState.mBitmap != null && mBitmapState.mBitmap.hasMipMap(); 2895769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy } 2905769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy 2915769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy /** 292ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Enables or disables anti-aliasing for this drawable. Anti-aliasing affects 293ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * the edges of the bitmap only so it applies only when the drawable is rotated. 294ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 295ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param aa True if the bitmap should be anti-aliased, false otherwise. 2965769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 2975769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @see #hasAntiAlias() 298ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAntiAlias(boolean aa) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setAntiAlias(aa); 3019891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3035769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy 3045769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy /** 3055769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * Indicates whether anti-aliasing is enabled for this drawable. 3065769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 3075769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @return True if anti-aliasing is enabled, false otherwise. 3085769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * 3095769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy * @see #setAntiAlias(boolean) 3105769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy */ 3115769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy public boolean hasAntiAlias() { 3125769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy return mBitmapState.mPaint.isAntiAlias(); 3135769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy } 3145769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFilterBitmap(boolean filter) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setFilterBitmap(filter); 3189891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setDither(dither); 3249891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 327ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 328ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Indicates the repeat behavior of this drawable on the X axis. 329ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 330ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat, 331ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise. 332ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Shader.TileMode getTileModeX() { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mTileModeX; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 337ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 338ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Indicates the repeat behavior of this drawable on the Y axis. 339ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 340ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat, 341ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise. 342ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Shader.TileMode getTileModeY() { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mTileModeY; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 347ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 348ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on the X axis. By default, the drawable 349ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 350ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 351ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 352ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 353ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param mode The repeat mode for this drawable. 354ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 355ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeY(android.graphics.Shader.TileMode) 356ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 357ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTileModeX(Shader.TileMode mode) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(mode, mBitmapState.mTileModeY); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 362ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 363ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on the Y axis. By default, the drawable 364ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 365ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 366ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 367ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 368ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param mode The repeat mode for this drawable. 369ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 370ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeX(android.graphics.Shader.TileMode) 371ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 372ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void setTileModeY(Shader.TileMode mode) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(mBitmapState.mTileModeX, mode); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 377ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 378ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on both axis. By default, the drawable 379ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 380ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 381ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 382ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 383ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param xmode The X repeat mode for this drawable. 384ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param ymode The Y repeat mode for this drawable. 385ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 386ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeX(android.graphics.Shader.TileMode) 387ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeY(android.graphics.Shader.TileMode) 388ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTileModeXY(Shader.TileMode xmode, Shader.TileMode ymode) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final BitmapState state = mBitmapState; 391ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy if (state.mTileModeX != xmode || state.mTileModeY != ymode) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mTileModeX = xmode; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mTileModeY = ymode; 3942660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy state.mRebuildShader = true; 3959891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() | mBitmapState.mChangingConfigurations; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(bounds); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = true; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap bitmap = mBitmap; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bitmap != null) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final BitmapState state = mBitmapState; 4152660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy if (state.mRebuildShader) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader.TileMode tmx = state.mTileModeX; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader.TileMode tmy = state.mTileModeY; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tmx == null && tmy == null) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mPaint.setShader(null); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 422ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy state.mPaint.setShader(new BitmapShader(bitmap, 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmx == null ? Shader.TileMode.CLAMP : tmx, 424ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy tmy == null ? Shader.TileMode.CLAMP : tmy)); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4262660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy state.mRebuildShader = false; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copyBounds(mDstRect); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader shader = state.mPaint.getShader(); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shader == null) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mApplyGravity) { 433b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio final int layoutDirection = getLayoutDirection(); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight, 435c0053223bedf33581b0830fb87be32c1f26e5372Fabrice Di Meglio getBounds(), mDstRect, layoutDirection); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = false; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mApplyGravity) { 441ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy copyBounds(mDstRect); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = false; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRect(mDstRect, state.mPaint); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 451ad4f70306b2089a273635b73a101fe48aa36cbe2Chet Haase int oldAlpha = mBitmapState.mPaint.getAlpha(); 452ad4f70306b2089a273635b73a101fe48aa36cbe2Chet Haase if (alpha != oldAlpha) { 453ad4f70306b2089a273635b73a101fe48aa36cbe2Chet Haase mBitmapState.mPaint.setAlpha(alpha); 454ad4f70306b2089a273635b73a101fe48aa36cbe2Chet Haase invalidateSelf(); 455ad4f70306b2089a273635b73a101fe48aa36cbe2Chet Haase } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 457b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 458b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 459b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 460b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mBitmapState.mPaint.getAlpha(); 461b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setColorFilter(cf); 4669891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A mutable BitmapDrawable still shares its Bitmap with any other Drawable 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that comes from the same resource. 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return This drawable. 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = new BitmapState(mBitmapState); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.inflate(r, parser, attrs); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.BitmapDrawable); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int id = a.getResourceId(com.android.internal.R.styleable.BitmapDrawable_src, 0); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException(parser.getPositionDescription() + 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ": <bitmap> requires a valid src attribute"); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Bitmap bitmap = BitmapFactory.decodeResource(r, id); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bitmap == null) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException(parser.getPositionDescription() + 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ": <bitmap> requires a valid src attribute"); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mBitmap = bitmap; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setBitmap(bitmap); 50311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn setTargetDensity(r.getDisplayMetrics()); 5045769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy setMipMap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_mipMap, 5055769fcd88a6b53aa9394d869a9428c80e61a1565Romain Guy bitmap.hasMipMap())); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Paint paint = mBitmapState.mPaint; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setAntiAlias(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_antialias, 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isAntiAlias())); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setFilterBitmap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_filter, 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isFilterBitmap())); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setDither(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_dither, 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isDither())); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setGravity(a.getInt(com.android.internal.R.styleable.BitmapDrawable_gravity, Gravity.FILL)); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tileMode = a.getInt(com.android.internal.R.styleable.BitmapDrawable_tileMode, -1); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tileMode != -1) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (tileMode) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 2: 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 53511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn return mBitmapWidth; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 54011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn return mBitmapHeight; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmapState.mGravity != Gravity.FILL) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.TRANSLUCENT; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap bm = mBitmap; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (bm == null || bm.hasAlpha() || mBitmapState.mPaint.getAlpha() < 255) ? 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ConstantState getConstantState() { 5556efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mBitmapState.mChangingConfigurations = getChangingConfigurations(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class BitmapState extends ConstantState { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap mBitmap; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mChangingConfigurations; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mGravity = Gravity.FILL; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS); 564ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy Shader.TileMode mTileModeX = null; 565ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy Shader.TileMode mTileModeY = null; 56611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; 5672660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy boolean mRebuildShader; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BitmapState(Bitmap bitmap) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmap = bitmap; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BitmapState(BitmapState bitmapState) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(bitmapState.mBitmap); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = bitmapState.mChangingConfigurations; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGravity = bitmapState.mGravity; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTileModeX = bitmapState.mTileModeX; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTileModeY = bitmapState.mTileModeY; 57911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mTargetDensity = bitmapState.mTargetDensity; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaint = new Paint(bitmapState.mPaint); 5812660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy mRebuildShader = bitmapState.mRebuildShader; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 586c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn return new BitmapDrawable(this, null); 587c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 5882660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy 589c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 590c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public Drawable newDrawable(Resources res) { 591c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn return new BitmapDrawable(this, res); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5932660a3ec8564918a243b1b02e3652c514bc93bfcRomain Guy 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChangingConfigurations; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 600c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn private BitmapDrawable(BitmapState state, Resources res) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = state; 602c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (res != null) { 603c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mTargetDensity = res.getDisplayMetrics().densityDpi; 604c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } else { 605e42143aa575dcb8ab0616080b2e9b4614a1a4167Jozef BABJAK mTargetDensity = state.mTargetDensity; 606c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 607ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy setBitmap(state != null ? state.mBitmap : null); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 610