BitmapDrawable.java revision ee0c116ab2bd5acdfe50db36441cf4784d3a10b4
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; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Shader; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.BitmapShader; 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 Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * BitmapDrawable from a file path, an input stream, through XML inflation, or from 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link android.graphics.Bitmap} object. 43dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code><bitmap></code> element. For more 44dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a 45dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also see the {@link android.graphics.Bitmap} class, which handles the management and 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transformation of raw bitmap graphics, and should be used when drawing to a 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.graphics.Canvas}. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_src 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_antialias 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_filter 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_dither 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_gravity 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#BitmapDrawable_tileMode 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BitmapDrawable extends Drawable { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed private static final int DEFAULT_PAINT_FLAGS = 62211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private BitmapState mBitmapState; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bitmap mBitmap; 65c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn private int mTargetDensity; 66c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mDstRect = new Rect(); // Gravity.apply() sets this 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mApplyGravity; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mRebuildShader; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 7211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 73c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn // These are scaled to match the target density. 7411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private int mBitmapWidth; 7511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private int mBitmapHeight; 7611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 7711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 7811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create an empty drawable, not dealing with density. 7911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources)} to ensure 8011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * that the drawable has correctly set its target density. 8111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 824a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable() { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = new BitmapState((Bitmap) null); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 8811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create an empty drawable, setting initial target density based on 8911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * the display metrics of the resources. 9011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 91ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 9211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public BitmapDrawable(Resources res) { 9311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapState = new BitmapState((Bitmap) null); 94c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 9511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 9611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 9711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 9811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create drawable from a bitmap, not dealing with density. 9911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure 10011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * that the drawable has correctly set its target density. 10111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 1024a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(Bitmap bitmap) { 104c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(bitmap), null); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 10811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Create drawable from a bitmap, setting initial target density based on 10911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * the display metrics of the resources. 11011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 11111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public BitmapDrawable(Resources res, Bitmap bitmap) { 112c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(bitmap), res); 113c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 11411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 11511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 116c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 117c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by opening a given file path and decoding the bitmap. 118c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, String)} to ensure 119c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * that the drawable has correctly set its target density. 120c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 12129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn @Deprecated 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(String filepath) { 123c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); 124c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (mBitmap == null) { 125c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); 126c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 127c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 128c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 129c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 130c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by opening a given file path and decoding the bitmap. 131c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 132ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 133c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public BitmapDrawable(Resources res, String filepath) { 134c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); 135c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmap == null) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 141c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 142c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by decoding a bitmap from the given input stream. 143c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * @deprecated Use {@link #BitmapDrawable(Resources, java.io.InputStream)} to ensure 144c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * that the drawable has correctly set its target density. 145c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 14629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn @Deprecated 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BitmapDrawable(java.io.InputStream is) { 148c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeStream(is)), null); 149c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (mBitmap == null) { 150c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); 151c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 152c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 153c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 154c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn /** 155c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn * Create a drawable by decoding a bitmap from the given input stream. 156c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn */ 157ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy @SuppressWarnings({"UnusedParameters"}) 158c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public BitmapDrawable(Resources res, java.io.InputStream is) { 159c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn this(new BitmapState(BitmapFactory.decodeStream(is)), null); 160c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mBitmapState.mTargetDensity = mTargetDensity; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmap == null) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 166ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 167ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Returns the paint used to render this drawable. 168ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Paint getPaint() { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mPaint; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 172ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy 173ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 174ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Returns the bitmap used by this drawable to render. May be null. 175ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Bitmap getBitmap() { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmap; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn private void computeBitmapSize() { 18111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity); 18211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity); 18311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 18411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setBitmap(Bitmap bitmap) { 1869891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (bitmap != mBitmap) { 1879891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmap = bitmap; 1889891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (bitmap != null) { 1899891e1fce5f29d0421d34aa481037417bd70853dChet Haase computeBitmapSize(); 1909891e1fce5f29d0421d34aa481037417bd70853dChet Haase } else { 1919891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmapWidth = mBitmapHeight = -1; 1929891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 1939891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the density scale at which this drawable will be rendered. This 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method assumes the drawable will be rendered at the same density as the 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified canvas. 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param canvas The Canvas from which the density scale must be obtained. 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 20511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(Canvas canvas) { 20811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn setTargetDensity(canvas.getDensity()); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the density scale at which this drawable will be rendered. 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param metrics The DisplayMetrics indicating the density scale for this drawable. 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 21611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 21711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(DisplayMetrics metrics) { 2209891e1fce5f29d0421d34aa481037417bd70853dChet Haase setTargetDensity(metrics.densityDpi); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Set the density at which this drawable will be rendered. 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param density The density scale for this drawable. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 22811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#setDensity(int) 22911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * @see android.graphics.Bitmap#getDensity() 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public void setTargetDensity(int density) { 2329891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mTargetDensity != density) { 2339891e1fce5f29d0421d34aa481037417bd70853dChet Haase mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density; 2349891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mBitmap != null) { 2359891e1fce5f29d0421d34aa481037417bd70853dChet Haase computeBitmapSize(); 2369891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 2379891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 23811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Get the gravity used to position/stretch the bitmap within its bounds. 24211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * See android.view.Gravity 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the gravity applied to the bitmap 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getGravity() { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mGravity; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Set the gravity used to position/stretch the bitmap within its bounds. 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project See android.view.Gravity 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 2549891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (mBitmapState.mGravity != gravity) { 2559891e1fce5f29d0421d34aa481037417bd70853dChet Haase mBitmapState.mGravity = gravity; 2569891e1fce5f29d0421d34aa481037417bd70853dChet Haase mApplyGravity = true; 2579891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2589891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 261ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 262ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Enables or disables anti-aliasing for this drawable. Anti-aliasing affects 263ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * the edges of the bitmap only so it applies only when the drawable is rotated. 264ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 265ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param aa True if the bitmap should be anti-aliased, false otherwise. 266ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAntiAlias(boolean aa) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setAntiAlias(aa); 2699891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFilterBitmap(boolean filter) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setFilterBitmap(filter); 2759891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setDither(dither); 2819891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 284ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 285ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Indicates the repeat behavior of this drawable on the X axis. 286ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 287ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat, 288ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise. 289ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Shader.TileMode getTileModeX() { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mTileModeX; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 294ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 295ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Indicates the repeat behavior of this drawable on the Y axis. 296ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 297ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat, 298ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise. 299ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Shader.TileMode getTileModeY() { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState.mTileModeY; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 304ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 305ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on the X axis. By default, the drawable 306ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 307ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 308ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 309ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 310ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param mode The repeat mode for this drawable. 311ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 312ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeY(android.graphics.Shader.TileMode) 313ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 314ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTileModeX(Shader.TileMode mode) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(mode, mBitmapState.mTileModeY); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 320ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on the Y axis. By default, the drawable 321ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 322ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 323ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 324ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 325ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param mode The repeat mode for this drawable. 326ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 327ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeX(android.graphics.Shader.TileMode) 328ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 329ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void setTileModeY(Shader.TileMode mode) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(mBitmapState.mTileModeX, mode); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 334ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy /** 335ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * Sets the repeat behavior of this drawable on both axis. By default, the drawable 336ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or 337ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap 338ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * is smaller than this drawable. 339ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 340ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param xmode The X repeat mode for this drawable. 341ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @param ymode The Y repeat mode for this drawable. 342ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * 343ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeX(android.graphics.Shader.TileMode) 344ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy * @see #setTileModeY(android.graphics.Shader.TileMode) 345ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTileModeXY(Shader.TileMode xmode, Shader.TileMode ymode) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final BitmapState state = mBitmapState; 348ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy if (state.mTileModeX != xmode || state.mTileModeY != ymode) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mTileModeX = xmode; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mTileModeY = ymode; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRebuildShader = true; 3529891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() | mBitmapState.mChangingConfigurations; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(bounds); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = true; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap bitmap = mBitmap; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bitmap != null) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final BitmapState state = mBitmapState; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRebuildShader) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader.TileMode tmx = state.mTileModeX; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader.TileMode tmy = state.mTileModeY; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tmx == null && tmy == null) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.mPaint.setShader(null); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 379ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy state.mPaint.setShader(new BitmapShader(bitmap, 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmx == null ? Shader.TileMode.CLAMP : tmx, 381ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy tmy == null ? Shader.TileMode.CLAMP : tmy)); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRebuildShader = false; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copyBounds(mDstRect); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Shader shader = state.mPaint.getShader(); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shader == null) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mApplyGravity) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight, 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getBounds(), mDstRect); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = false; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mApplyGravity) { 397ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy copyBounds(mDstRect); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplyGravity = false; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRect(mDstRect, state.mPaint); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setAlpha(alpha); 4089891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mPaint.setColorFilter(cf); 4149891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A mutable BitmapDrawable still shares its Bitmap with any other Drawable 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that comes from the same resource. 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return This drawable. 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = new BitmapState(mBitmapState); 427ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy mRebuildShader = true; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.inflate(r, parser, attrs); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.BitmapDrawable); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int id = a.getResourceId(com.android.internal.R.styleable.BitmapDrawable_src, 0); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException(parser.getPositionDescription() + 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ": <bitmap> requires a valid src attribute"); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Bitmap bitmap = BitmapFactory.decodeResource(r, id); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bitmap == null) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException(parser.getPositionDescription() + 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ": <bitmap> requires a valid src attribute"); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState.mBitmap = bitmap; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setBitmap(bitmap); 45211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn setTargetDensity(r.getDisplayMetrics()); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Paint paint = mBitmapState.mPaint; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setAntiAlias(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_antialias, 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isAntiAlias())); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setFilterBitmap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_filter, 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isFilterBitmap())); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.setDither(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_dither, 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.isDither())); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setGravity(a.getInt(com.android.internal.R.styleable.BitmapDrawable_gravity, Gravity.FILL)); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tileMode = a.getInt(com.android.internal.R.styleable.BitmapDrawable_tileMode, -1); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tileMode != -1) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (tileMode) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 2: 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 48211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn return mBitmapWidth; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 48711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn return mBitmapHeight; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBitmapState.mGravity != Gravity.FILL) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.TRANSLUCENT; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap bm = mBitmap; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (bm == null || bm.hasAlpha() || mBitmapState.mPaint.getAlpha() < 255) ? 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ConstantState getConstantState() { 5026efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mBitmapState.mChangingConfigurations = getChangingConfigurations(); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmapState; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class BitmapState extends ConstantState { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bitmap mBitmap; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mChangingConfigurations; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mGravity = Gravity.FILL; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS); 511ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy Shader.TileMode mTileModeX = null; 512ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy Shader.TileMode mTileModeY = null; 51311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BitmapState(Bitmap bitmap) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmap = bitmap; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BitmapState(BitmapState bitmapState) { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(bitmapState.mBitmap); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = bitmapState.mChangingConfigurations; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGravity = bitmapState.mGravity; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTileModeX = bitmapState.mTileModeX; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTileModeY = bitmapState.mTileModeY; 52511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn mTargetDensity = bitmapState.mTargetDensity; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaint = new Paint(bitmapState.mPaint); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 531c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn return new BitmapDrawable(this, null); 532c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 533c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 534c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 535c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public Drawable newDrawable(Resources res) { 536c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn return new BitmapDrawable(this, res); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChangingConfigurations; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 545c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn private BitmapDrawable(BitmapState state, Resources res) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmapState = state; 547c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn if (res != null) { 548c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mTargetDensity = res.getDisplayMetrics().densityDpi; 549c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } else if (state != null) { 550c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mTargetDensity = state.mTargetDensity; 551c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } else { 552c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; 553c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 554ee0c116ab2bd5acdfe50db36441cf4784d3a10b4Romain Guy setBitmap(state != null ? state.mBitmap : null); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 557