summaryrefslogtreecommitdiff
path: root/core/java/android/widget/ImageView.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/widget/ImageView.java
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/widget/ImageView.java')
-rw-r--r--core/java/android/widget/ImageView.java891
1 files changed, 0 insertions, 891 deletions
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
deleted file mode 100644
index 94d1bd175c7a..000000000000
--- a/core/java/android/widget/ImageView.java
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.widget;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.RectF;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.RemoteViews.RemoteView;
-
-
-/**
- * Displays an arbitrary image, such as an icon. The ImageView class
- * can load images from various sources (such as resources or content
- * providers), takes care of computing its measurement from the image so that
- * it can be used in any layout manager, and provides various display options
- * such as scaling and tinting.
- *
- * @attr ref android.R.styleable#ImageView_adjustViewBounds
- * @attr ref android.R.styleable#ImageView_src
- * @attr ref android.R.styleable#ImageView_maxWidth
- * @attr ref android.R.styleable#ImageView_maxHeight
- * @attr ref android.R.styleable#ImageView_tint
- * @attr ref android.R.styleable#ImageView_scaleType
- * @attr ref android.R.styleable#ImageView_cropToPadding
- */
-@RemoteView
-public class ImageView extends View {
- // settable by the client
- private Uri mUri;
- private int mResource = 0;
- private Matrix mMatrix;
- private ScaleType mScaleType;
- private boolean mHaveFrame = false;
- private boolean mAdjustViewBounds = false;
- private int mMaxWidth = Integer.MAX_VALUE;
- private int mMaxHeight = Integer.MAX_VALUE;
-
- // these are applied to the drawable
- private ColorFilter mColorFilter;
- private int mAlpha = 255;
- private int mViewAlphaScale = 256;
-
- private Drawable mDrawable = null;
- private int[] mState = null;
- private boolean mMergeState = false;
- private int mLevel = 0;
- private int mDrawableWidth;
- private int mDrawableHeight;
- private Matrix mDrawMatrix = null;
-
- // Avoid allocations...
- private RectF mTempSrc = new RectF();
- private RectF mTempDst = new RectF();
-
- private boolean mCropToPadding;
-
- private boolean mBaselineAligned = false;
-
- private static final ScaleType[] sScaleTypeArray = {
- ScaleType.MATRIX,
- ScaleType.FIT_XY,
- ScaleType.FIT_START,
- ScaleType.FIT_CENTER,
- ScaleType.FIT_END,
- ScaleType.CENTER,
- ScaleType.CENTER_CROP,
- ScaleType.CENTER_INSIDE
- };
-
- public ImageView(Context context) {
- super(context);
- initImageView();
- }
-
- public ImageView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initImageView();
-
- TypedArray a = context.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.ImageView, defStyle, 0);
-
- Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
- if (d != null) {
- setImageDrawable(d);
- }
-
- mBaselineAligned = a.getBoolean(
- com.android.internal.R.styleable.ImageView_baselineAlignBottom, false);
-
- setAdjustViewBounds(
- a.getBoolean(com.android.internal.R.styleable.ImageView_adjustViewBounds,
- false));
-
- setMaxWidth(a.getDimensionPixelSize(
- com.android.internal.R.styleable.ImageView_maxWidth, Integer.MAX_VALUE));
-
- setMaxHeight(a.getDimensionPixelSize(
- com.android.internal.R.styleable.ImageView_maxHeight, Integer.MAX_VALUE));
-
- int index = a.getInt(com.android.internal.R.styleable.ImageView_scaleType, -1);
- if (index >= 0) {
- setScaleType(sScaleTypeArray[index]);
- }
-
- int tint = a.getInt(com.android.internal.R.styleable.ImageView_tint, 0);
- if (tint != 0) {
- setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
- }
-
- mCropToPadding = a.getBoolean(
- com.android.internal.R.styleable.ImageView_cropToPadding, false);
-
- a.recycle();
-
- //need inflate syntax/reader for matrix
- }
-
- private void initImageView() {
- mMatrix = new Matrix();
- mScaleType = ScaleType.FIT_CENTER;
- }
-
- @Override
- protected boolean verifyDrawable(Drawable dr) {
- return mDrawable == dr || super.verifyDrawable(dr);
- }
-
- @Override
- public void invalidateDrawable(Drawable dr) {
- if (dr == mDrawable) {
- /* we invalidate the whole view in this case because it's very
- * hard to know where the drawable actually is. This is made
- * complicated because of the offsets and transformations that
- * can be applied. In theory we could get the drawable's bounds
- * and run them through the transformation and offsets, but this
- * is probably not worth the effort.
- */
- invalidate();
- } else {
- super.invalidateDrawable(dr);
- }
- }
-
- @Override
- protected boolean onSetAlpha(int alpha) {
- if (getBackground() == null) {
- int scale = alpha + (alpha >> 7);
- if (mViewAlphaScale != scale) {
- mViewAlphaScale = scale;
- applyColorMod();
- }
- return true;
- }
- return false;
- }
-
- /**
- * Set this to true if you want the ImageView to adjust its bounds
- * to preserve the aspect ratio of its drawable.
- * @param adjustViewBounds Whether to adjust the bounds of this view
- * to presrve the original aspect ratio of the drawable
- *
- * @attr ref android.R.styleable#ImageView_adjustViewBounds
- */
- @android.view.RemotableViewMethod
- public void setAdjustViewBounds(boolean adjustViewBounds) {
- mAdjustViewBounds = adjustViewBounds;
- if (adjustViewBounds) {
- setScaleType(ScaleType.FIT_CENTER);
- }
- }
-
- /**
- * An optional argument to supply a maximum width for this view. Only valid if
- * {@link #setAdjustViewBounds} has been set to true. To set an image to be a maximum of 100 x
- * 100 while preserving the original aspect ratio, do the following: 1) set adjustViewBounds to
- * true 2) set maxWidth and maxHeight to 100 3) set the height and width layout params to
- * WRAP_CONTENT.
- *
- * <p>
- * Note that this view could be still smaller than 100 x 100 using this approach if the original
- * image is small. To set an image to a fixed size, specify that size in the layout params and
- * then use {@link #setScaleType} to determine how to fit the image within the bounds.
- * </p>
- *
- * @param maxWidth maximum width for this view
- *
- * @attr ref android.R.styleable#ImageView_maxWidth
- */
- @android.view.RemotableViewMethod
- public void setMaxWidth(int maxWidth) {
- mMaxWidth = maxWidth;
- }
-
- /**
- * An optional argument to supply a maximum height for this view. Only valid if
- * {@link #setAdjustViewBounds} has been set to true. To set an image to be a maximum of 100 x
- * 100 while preserving the original aspect ratio, do the following: 1) set adjustViewBounds to
- * true 2) set maxWidth and maxHeight to 100 3) set the height and width layout params to
- * WRAP_CONTENT.
- *
- * <p>
- * Note that this view could be still smaller than 100 x 100 using this approach if the original
- * image is small. To set an image to a fixed size, specify that size in the layout params and
- * then use {@link #setScaleType} to determine how to fit the image within the bounds.
- * </p>
- *
- * @param maxHeight maximum height for this view
- *
- * @attr ref android.R.styleable#ImageView_maxHeight
- */
- @android.view.RemotableViewMethod
- public void setMaxHeight(int maxHeight) {
- mMaxHeight = maxHeight;
- }
-
- /** Return the view's drawable, or null if no drawable has been
- assigned.
- */
- public Drawable getDrawable() {
- return mDrawable;
- }
-
- /**
- * Sets a drawable as the content of this ImageView.
- *
- * @param resId the resource identifier of the the drawable
- *
- * @attr ref android.R.styleable#ImageView_src
- */
- @android.view.RemotableViewMethod
- public void setImageResource(int resId) {
- if (mUri != null || mResource != resId) {
- updateDrawable(null);
- mResource = resId;
- mUri = null;
- resolveUri();
- requestLayout();
- invalidate();
- }
- }
-
- /**
- * Sets the content of this ImageView to the specified Uri.
- *
- * @param uri The Uri of an image
- */
- @android.view.RemotableViewMethod
- public void setImageURI(Uri uri) {
- if (mResource != 0 ||
- (mUri != uri &&
- (uri == null || mUri == null || !uri.equals(mUri)))) {
- updateDrawable(null);
- mResource = 0;
- mUri = uri;
- resolveUri();
- requestLayout();
- invalidate();
- }
- }
-
-
- /**
- * Sets a drawable as the content of this ImageView.
- *
- * @param drawable The drawable to set
- */
- public void setImageDrawable(Drawable drawable) {
- if (mDrawable != drawable) {
- mResource = 0;
- mUri = null;
- updateDrawable(drawable);
- requestLayout();
- invalidate();
- }
- }
-
- /**
- * Sets a Bitmap as the content of this ImageView.
- *
- * @param bm The bitmap to set
- */
- @android.view.RemotableViewMethod
- public void setImageBitmap(Bitmap bm) {
- // if this is used frequently, may handle bitmaps explicitly
- // to reduce the intermediate drawable object
- setImageDrawable(new BitmapDrawable(bm));
- }
-
- public void setImageState(int[] state, boolean merge) {
- mState = state;
- mMergeState = merge;
- if (mDrawable != null) {
- refreshDrawableState();
- resizeFromDrawable();
- }
- }
-
- @Override
- public void setSelected(boolean selected) {
- super.setSelected(selected);
- resizeFromDrawable();
- }
-
- @android.view.RemotableViewMethod
- public void setImageLevel(int level) {
- mLevel = level;
- if (mDrawable != null) {
- mDrawable.setLevel(level);
- resizeFromDrawable();
- }
- }
-
- /**
- * Options for scaling the bounds of an image to the bounds of this view.
- */
- public enum ScaleType {
- /**
- * Scale using the image matrix when drawing. The image matrix can be set using
- * {@link ImageView#setImageMatrix(Matrix)}. From XML, use this syntax:
- * <code>android:scaleType="matrix"</code>.
- */
- MATRIX (0),
- /**
- * Scale the image using {@link Matrix.ScaleToFit#FILL}.
- * From XML, use this syntax: <code>android:scaleType="fitXY"</code>.
- */
- FIT_XY (1),
- /**
- * Scale the image using {@link Matrix.ScaleToFit#START}.
- * From XML, use this syntax: <code>android:scaleType="fitStart"</code>.
- */
- FIT_START (2),
- /**
- * Scale the image using {@link Matrix.ScaleToFit#CENTER}.
- * From XML, use this syntax:
- * <code>android:scaleType="fitCenter"</code>.
- */
- FIT_CENTER (3),
- /**
- * Scale the image using {@link Matrix.ScaleToFit#END}.
- * From XML, use this syntax: <code>android:scaleType="fitEnd"</code>.
- */
- FIT_END (4),
- /**
- * Center the image in the view, but perform no scaling.
- * From XML, use this syntax: <code>android:scaleType="center"</code>.
- */
- CENTER (5),
- /**
- * Scale the image uniformly (maintain the image's aspect ratio) so
- * that both dimensions (width and height) of the image will be equal
- * to or larger than the corresponding dimension of the view
- * (minus padding). The image is then centered in the view.
- * From XML, use this syntax: <code>android:scaleType="centerCrop"</code>.
- */
- CENTER_CROP (6),
- /**
- * Scale the image uniformly (maintain the image's aspect ratio) so
- * that both dimensions (width and height) of the image will be equal
- * to or less than the corresponding dimension of the view
- * (minus padding). The image is then centered in the view.
- * From XML, use this syntax: <code>android:scaleType="centerInside"</code>.
- */
- CENTER_INSIDE (7);
-
- ScaleType(int ni) {
- nativeInt = ni;
- }
- final int nativeInt;
- }
-
- /**
- * Controls how the image should be resized or moved to match the size
- * of this ImageView.
- *
- * @param scaleType The desired scaling mode.
- *
- * @attr ref android.R.styleable#ImageView_scaleType
- */
- public void setScaleType(ScaleType scaleType) {
- if (scaleType == null) {
- throw new NullPointerException();
- }
-
- if (mScaleType != scaleType) {
- mScaleType = scaleType;
-
- setWillNotCacheDrawing(mScaleType == ScaleType.CENTER);
-
- requestLayout();
- invalidate();
- }
- }
-
- /**
- * Return the current scale type in use by this ImageView.
- *
- * @see ImageView.ScaleType
- *
- * @attr ref android.R.styleable#ImageView_scaleType
- */
- public ScaleType getScaleType() {
- return mScaleType;
- }
-
- /** Return the view's optional matrix. This is applied to the
- view's drawable when it is drawn. If there is not matrix,
- this method will return null.
- Do not change this matrix in place. If you want a different matrix
- applied to the drawable, be sure to call setImageMatrix().
- */
- public Matrix getImageMatrix() {
- return mMatrix;
- }
-
- public void setImageMatrix(Matrix matrix) {
- // collaps null and identity to just null
- if (matrix != null && matrix.isIdentity()) {
- matrix = null;
- }
-
- // don't invalidate unless we're actually changing our matrix
- if (matrix == null && !mMatrix.isIdentity() ||
- matrix != null && !mMatrix.equals(matrix)) {
- mMatrix.set(matrix);
- invalidate();
- }
- }
-
- private void resolveUri() {
- if (mDrawable != null) {
- return;
- }
-
- Resources rsrc = getResources();
- if (rsrc == null) {
- return;
- }
-
- Drawable d = null;
-
- if (mResource != 0) {
- try {
- d = rsrc.getDrawable(mResource);
- } catch (Exception e) {
- Log.w("ImageView", "Unable to find resource: " + mResource, e);
- // Don't try again.
- mUri = null;
- }
- } else if (mUri != null) {
- if ("content".equals(mUri.getScheme())) {
- try {
- d = Drawable.createFromStream(
- mContext.getContentResolver().openInputStream(mUri),
- null);
- } catch (Exception e) {
- Log.w("ImageView", "Unable to open content: " + mUri, e);
- }
- } else {
- d = Drawable.createFromPath(mUri.toString());
- }
-
- if (d == null) {
- System.out.println("resolveUri failed on bad bitmap uri: "
- + mUri);
- // Don't try again.
- mUri = null;
- }
- } else {
- return;
- }
-
- updateDrawable(d);
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- if (mState == null) {
- return super.onCreateDrawableState(extraSpace);
- } else if (!mMergeState) {
- return mState;
- } else {
- return mergeDrawableStates(
- super.onCreateDrawableState(extraSpace + mState.length), mState);
- }
- }
-
- private void updateDrawable(Drawable d) {
- if (mDrawable != null) {
- mDrawable.setCallback(null);
- unscheduleDrawable(mDrawable);
- }
- mDrawable = d;
- if (d != null) {
- d.setCallback(this);
- if (d.isStateful()) {
- d.setState(getDrawableState());
- }
- d.setLevel(mLevel);
- mDrawableWidth = d.getIntrinsicWidth();
- mDrawableHeight = d.getIntrinsicHeight();
- applyColorMod();
- configureBounds();
- }
- }
-
- private void resizeFromDrawable() {
- Drawable d = mDrawable;
- if (d != null) {
- int w = d.getIntrinsicWidth();
- if (w < 0) w = mDrawableWidth;
- int h = d.getIntrinsicHeight();
- if (h < 0) h = mDrawableHeight;
- if (w != mDrawableWidth || h != mDrawableHeight) {
- mDrawableWidth = w;
- mDrawableHeight = h;
- requestLayout();
- }
- }
- }
-
- private static final Matrix.ScaleToFit[] sS2FArray = {
- Matrix.ScaleToFit.FILL,
- Matrix.ScaleToFit.START,
- Matrix.ScaleToFit.CENTER,
- Matrix.ScaleToFit.END
- };
-
- private static Matrix.ScaleToFit scaleTypeToScaleToFit(ScaleType st) {
- // ScaleToFit enum to their corresponding Matrix.ScaleToFit values
- return sS2FArray[st.nativeInt - 1];
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- resolveUri();
- int w;
- int h;
-
- // Desired aspect ratio of the view's contents (not including padding)
- float desiredAspect = 0.0f;
-
- // We are allowed to change the view's width
- boolean resizeWidth = false;
-
- // We are allowed to change the view's height
- boolean resizeHeight = false;
-
- if (mDrawable == null) {
- // If no drawable, its intrinsic size is 0.
- mDrawableWidth = -1;
- mDrawableHeight = -1;
- w = h = 0;
- } else {
- w = mDrawableWidth;
- h = mDrawableHeight;
- if (w <= 0) w = 1;
- if (h <= 0) h = 1;
-
- // We are supposed to adjust view bounds to match the aspect
- // ratio of our drawable. See if that is possible.
- if (mAdjustViewBounds) {
-
- int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
-
- resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
- resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
-
- desiredAspect = (float)w/(float)h;
- }
- }
-
- int pleft = mPaddingLeft;
- int pright = mPaddingRight;
- int ptop = mPaddingTop;
- int pbottom = mPaddingBottom;
-
- int widthSize;
- int heightSize;
-
- if (resizeWidth || resizeHeight) {
- /* If we get here, it means we want to resize to match the
- drawables aspect ratio, and we have the freedom to change at
- least one dimension.
- */
-
- // Get the max possible width given our constraints
- widthSize = resolveAdjustedSize(w + pleft + pright,
- mMaxWidth, widthMeasureSpec);
-
- // Get the max possible height given our constraints
- heightSize = resolveAdjustedSize(h + ptop + pbottom,
- mMaxHeight, heightMeasureSpec);
-
- if (desiredAspect != 0.0f) {
- // See what our actual aspect ratio is
- float actualAspect = (float)(widthSize - pleft - pright) /
- (heightSize - ptop - pbottom);
-
- if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {
-
- boolean done = false;
-
- // Try adjusting width to be proportional to height
- if (resizeWidth) {
- int newWidth = (int)(desiredAspect *
- (heightSize - ptop - pbottom))
- + pleft + pright;
- if (newWidth <= widthSize) {
- widthSize = newWidth;
- done = true;
- }
- }
-
- // Try adjusting height to be proportional to width
- if (!done && resizeHeight) {
- int newHeight = (int)((widthSize - pleft - pright)
- / desiredAspect) + ptop + pbottom;
- if (newHeight <= heightSize) {
- heightSize = newHeight;
- }
- }
- }
- }
- } else {
- /* We are either don't want to preserve the drawables aspect ratio,
- or we are not allowed to change view dimensions. Just measure in
- the normal way.
- */
- w += pleft + pright;
- h += ptop + pbottom;
-
- w = Math.max(w, getSuggestedMinimumWidth());
- h = Math.max(h, getSuggestedMinimumHeight());
-
- widthSize = resolveSize(w, widthMeasureSpec);
- heightSize = resolveSize(h, heightMeasureSpec);
- }
-
- setMeasuredDimension(widthSize, heightSize);
- }
-
- private int resolveAdjustedSize(int desiredSize, int maxSize,
- int measureSpec) {
- int result = desiredSize;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
- switch (specMode) {
- case MeasureSpec.UNSPECIFIED:
- /* Parent says we can be as big as we want. Just don't be larger
- than max size imposed on ourselves.
- */
- result = Math.min(desiredSize, maxSize);
- break;
- case MeasureSpec.AT_MOST:
- // Parent says we can be as big as we want, up to specSize.
- // Don't be larger than specSize, and don't be larger than
- // the max size imposed on ourselves.
- result = Math.min(Math.min(desiredSize, specSize), maxSize);
- break;
- case MeasureSpec.EXACTLY:
- // No choice. Do what we are told.
- result = specSize;
- break;
- }
- return result;
- }
-
- @Override
- protected boolean setFrame(int l, int t, int r, int b) {
- boolean changed = super.setFrame(l, t, r, b);
- mHaveFrame = true;
- configureBounds();
- return changed;
- }
-
- private void configureBounds() {
- if (mDrawable == null || !mHaveFrame) {
- return;
- }
-
- int dwidth = mDrawableWidth;
- int dheight = mDrawableHeight;
-
- int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
- int vheight = getHeight() - mPaddingTop - mPaddingBottom;
-
- boolean fits = (dwidth < 0 || vwidth == dwidth) &&
- (dheight < 0 || vheight == dheight);
-
- if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
- /* If the drawable has no intrinsic size, or we're told to
- scaletofit, then we just fill our entire view.
- */
- mDrawable.setBounds(0, 0, vwidth, vheight);
- mDrawMatrix = null;
- } else {
- // We need to do the scaling ourself, so have the drawable
- // use its native size.
- mDrawable.setBounds(0, 0, dwidth, dheight);
-
- if (ScaleType.MATRIX == mScaleType) {
- // Use the specified matrix as-is.
- if (mMatrix.isIdentity()) {
- mDrawMatrix = null;
- } else {
- mDrawMatrix = mMatrix;
- }
- } else if (fits) {
- // The bitmap fits exactly, no transform needed.
- mDrawMatrix = null;
- } else if (ScaleType.CENTER == mScaleType) {
- // Center bitmap in view, no scaling.
- mDrawMatrix = mMatrix;
- mDrawMatrix.setTranslate((vwidth - dwidth) * 0.5f,
- (vheight - dheight) * 0.5f);
- } else if (ScaleType.CENTER_CROP == mScaleType) {
- mDrawMatrix = mMatrix;
-
- float scale;
- float dx = 0, dy = 0;
-
- if (dwidth * vheight > vwidth * dheight) {
- scale = (float) vheight / (float) dheight;
- dx = (vwidth - dwidth * scale) * 0.5f;
- } else {
- scale = (float) vwidth / (float) dwidth;
- dy = (vheight - dheight * scale) * 0.5f;
- }
-
- mDrawMatrix.setScale(scale, scale);
- mDrawMatrix.postTranslate(dx, dy);
- } else if (ScaleType.CENTER_INSIDE == mScaleType) {
- mDrawMatrix = mMatrix;
- float scale;
- float dx;
- float dy;
-
- if (dwidth <= vwidth && dheight <= vheight) {
- scale = 1.0f;
- } else {
- scale = Math.min((float) vwidth / (float) dwidth,
- (float) vheight / (float) dheight);
- }
-
- dx = (vwidth - dwidth * scale) * 0.5f;
- dy = (vheight - dheight * scale) * 0.5f;
-
- mDrawMatrix.setScale(scale, scale);
- mDrawMatrix.postTranslate(dx, dy);
- } else {
- // Generate the required transform.
- mTempSrc.set(0, 0, dwidth, dheight);
- mTempDst.set(0, 0, vwidth, vheight);
-
- mDrawMatrix = mMatrix;
- mDrawMatrix.setRectToRect(mTempSrc, mTempDst,
- scaleTypeToScaleToFit(mScaleType));
- }
- }
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- Drawable d = mDrawable;
- if (d != null && d.isStateful()) {
- d.setState(getDrawableState());
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (mDrawable == null) {
- return; // couldn't resolve the URI
- }
-
- if (mDrawableWidth == 0 || mDrawableHeight == 0) {
- return; // nothing to draw (empty bounds)
- }
-
- if (mDrawMatrix == null && mPaddingTop == 0 && mPaddingLeft == 0) {
- mDrawable.draw(canvas);
- } else {
- int saveCount = canvas.getSaveCount();
- canvas.save();
-
- if (mCropToPadding) {
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop,
- scrollX + mRight - mLeft - mPaddingRight,
- scrollY + mBottom - mTop - mPaddingBottom);
- }
-
- canvas.translate(mPaddingLeft, mPaddingTop);
-
- if (mDrawMatrix != null) {
- canvas.concat(mDrawMatrix);
- }
- mDrawable.draw(canvas);
- canvas.restoreToCount(saveCount);
- }
- }
-
- @Override
- public int getBaseline() {
- return mBaselineAligned ? getHeight() : -1;
- }
-
- /**
- * Set a tinting option for the image.
- *
- * @param color Color tint to apply.
- * @param mode How to apply the color. The standard mode is
- * {@link PorterDuff.Mode#SRC_ATOP}
- *
- * @attr ref android.R.styleable#ImageView_tint
- */
- public final void setColorFilter(int color, PorterDuff.Mode mode) {
- setColorFilter(new PorterDuffColorFilter(color, mode));
- }
-
- public final void clearColorFilter() {
- setColorFilter(null);
- }
-
- /**
- * Apply an arbitrary colorfilter to the image.
- *
- * @param cf the colorfilter to apply (may be null)
- */
- public void setColorFilter(ColorFilter cf) {
- if (mColorFilter != cf) {
- mColorFilter = cf;
- applyColorMod();
- invalidate();
- }
- }
-
- public void setAlpha(int alpha) {
- alpha &= 0xFF; // keep it legal
- if (mAlpha != alpha) {
- mAlpha = alpha;
- applyColorMod();
- invalidate();
- }
- }
-
- private void applyColorMod() {
- if (mDrawable != null) {
- mDrawable.setColorFilter(mColorFilter);
- mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
- }
- }
-}