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