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