/* * Copyright (C) 2015 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 com.android.messaging.ui; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.view.Gravity; import com.android.messaging.util.exif.ExifInterface; /** * A drawable that draws a bitmap in a flipped or rotated orientation without having to adjust the * bitmap */ public class OrientedBitmapDrawable extends BitmapDrawable { private final ExifInterface.OrientationParams mOrientationParams; private final Rect mDstRect; private int mCenterX; private int mCenterY; private boolean mApplyGravity; public static BitmapDrawable create(final int orientation, Resources res, Bitmap bitmap) { if (orientation <= ExifInterface.Orientation.TOP_LEFT) { // No need to adjust the bitmap, so just use a regular BitmapDrawable return new BitmapDrawable(res, bitmap); } else { // Create an oriented bitmap drawable return new OrientedBitmapDrawable(orientation, res, bitmap); } } private OrientedBitmapDrawable(final int orientation, Resources res, Bitmap bitmap) { super(res, bitmap); mOrientationParams = ExifInterface.getOrientationParams(orientation); mApplyGravity = true; mDstRect = new Rect(); } @Override public int getIntrinsicWidth() { if (mOrientationParams.invertDimensions) { return super.getIntrinsicHeight(); } return super.getIntrinsicWidth(); } @Override public int getIntrinsicHeight() { if (mOrientationParams.invertDimensions) { return super.getIntrinsicWidth(); } return super.getIntrinsicHeight(); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mApplyGravity = true; } @Override public void draw(Canvas canvas) { if (mApplyGravity) { Gravity.apply(getGravity(), getIntrinsicWidth(), getIntrinsicHeight(), getBounds(), mDstRect); mCenterX = mDstRect.centerX(); mCenterY = mDstRect.centerY(); if (mOrientationParams.invertDimensions) { final Matrix matrix = new Matrix(); matrix.setRotate(mOrientationParams.rotation, mCenterX, mCenterY); final RectF rotatedRect = new RectF(mDstRect); matrix.mapRect(rotatedRect); mDstRect.set((int) rotatedRect.left, (int) rotatedRect.top, (int) rotatedRect.right, (int) rotatedRect.bottom); } mApplyGravity = false; } canvas.save(); canvas.scale(mOrientationParams.scaleX, mOrientationParams.scaleY, mCenterX, mCenterY); canvas.rotate(mOrientationParams.rotation, mCenterX, mCenterY); canvas.drawBitmap(getBitmap(), (Rect) null, mDstRect, getPaint()); canvas.restore(); } }