1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.ui; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Resources; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Bitmap; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Canvas; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Matrix; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Rect; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.RectF; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.drawable.BitmapDrawable; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.Gravity; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.exif.ExifInterface; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A drawable that draws a bitmap in a flipped or rotated orientation without having to adjust the 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * bitmap 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class OrientedBitmapDrawable extends BitmapDrawable { 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final ExifInterface.OrientationParams mOrientationParams; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final Rect mDstRect; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private int mCenterX; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private int mCenterY; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private boolean mApplyGravity; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static BitmapDrawable create(final int orientation, Resources res, Bitmap bitmap) { 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (orientation <= ExifInterface.Orientation.TOP_LEFT) { 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // No need to adjust the bitmap, so just use a regular BitmapDrawable 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new BitmapDrawable(res, bitmap); 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Create an oriented bitmap drawable 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new OrientedBitmapDrawable(orientation, res, bitmap); 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private OrientedBitmapDrawable(final int orientation, Resources res, Bitmap bitmap) { 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(res, bitmap); 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mOrientationParams = ExifInterface.getOrientationParams(orientation); 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApplyGravity = true; 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mDstRect = new Rect(); 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getIntrinsicWidth() { 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mOrientationParams.invertDimensions) { 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return super.getIntrinsicHeight(); 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return super.getIntrinsicWidth(); 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getIntrinsicHeight() { 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mOrientationParams.invertDimensions) { 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return super.getIntrinsicWidth(); 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return super.getIntrinsicHeight(); 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected void onBoundsChange(Rect bounds) { 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super.onBoundsChange(bounds); 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApplyGravity = true; 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void draw(Canvas canvas) { 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mApplyGravity) { 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Gravity.apply(getGravity(), getIntrinsicWidth(), getIntrinsicHeight(), getBounds(), 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mDstRect); 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mCenterX = mDstRect.centerX(); 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mCenterY = mDstRect.centerY(); 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mOrientationParams.invertDimensions) { 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Matrix matrix = new Matrix(); 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd matrix.setRotate(mOrientationParams.rotation, mCenterX, mCenterY); 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final RectF rotatedRect = new RectF(mDstRect); 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd matrix.mapRect(rotatedRect); 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mDstRect.set((int) rotatedRect.left, (int) rotatedRect.top, (int) rotatedRect.right, 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd (int) rotatedRect.bottom); 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApplyGravity = false; 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canvas.save(); 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canvas.scale(mOrientationParams.scaleX, mOrientationParams.scaleY, mCenterX, mCenterY); 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canvas.rotate(mOrientationParams.rotation, mCenterX, mCenterY); 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canvas.drawBitmap(getBitmap(), (Rect) null, mDstRect, getPaint()); 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd canvas.restore(); 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 105