1/* 2 * Copyright (C) 2010 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 17package com.android.photoeditor; 18 19import android.graphics.Matrix; 20import android.graphics.RectF; 21import android.view.View; 22 23/** 24 * Utils for rectangles/bounds related calculations. 25 */ 26public class RectUtils { 27 28 private static final float MATH_PI = (float) Math.PI; 29 private static final float DEGREES_TO_RADIAN = MATH_PI / 180.0f; 30 31 /** 32 * Gets straighten matrix for the given bounds and degrees. 33 */ 34 public static void getStraightenMatrix(RectF bounds, float degrees, Matrix matrix) { 35 matrix.reset(); 36 if ((degrees != 0) && !bounds.isEmpty()) { 37 float w = bounds.width() / 2; 38 float h = bounds.height() / 2; 39 float adjustAngle; 40 if ((degrees < 0 && w > h) || (degrees > 0 && w <= h)) { 41 // The top left point is the boundary. 42 adjustAngle = (float) Math.atan(h / -w) + MATH_PI + degrees * DEGREES_TO_RADIAN; 43 } else { 44 // The top right point is the boundary. 45 adjustAngle = (float) Math.atan(h / w) - MATH_PI + degrees * DEGREES_TO_RADIAN; 46 } 47 float radius = (float) Math.hypot(w, h); 48 float scaleX = (float) Math.abs(radius * Math.cos(adjustAngle)) / w; 49 float scaleY = (float) Math.abs(radius * Math.sin(adjustAngle)) / h; 50 float scale = Math.max(scaleX, scaleY); 51 52 postRotateMatrix(degrees, new RectF(bounds), matrix); 53 matrix.postScale(scale, scale); 54 } 55 } 56 57 /** 58 * Post rotates the matrix and bounds for the given bounds and degrees. 59 */ 60 public static void postRotateMatrix(float degrees, RectF bounds, Matrix matrix) { 61 matrix.postRotate(degrees); 62 matrix.mapRect(bounds); 63 matrix.postTranslate(-bounds.left, -bounds.top); 64 } 65 66 /** 67 * Post translates the matrix to center the given bounds inside the view. 68 */ 69 public static void postCenterMatrix(RectF contentBounds, View view, Matrix matrix) { 70 matrix.postTranslate((view.getWidth() - contentBounds.width()) / 2, 71 (view.getHeight() - contentBounds.height()) / 2); 72 } 73 74 /** 75 * Gets the proper scale value that scales down the content and keeps its aspect ratio to 76 * display inside the view. 77 */ 78 public static float getDisplayScale(RectF contentBounds, View view) { 79 if (contentBounds.isEmpty()) { 80 return 1; 81 } 82 83 float scale = Math.min(view.getWidth() / contentBounds.width(), 84 view.getHeight() / contentBounds.height()); 85 // Avoid scaling up the content. 86 return Math.min(scale, 1); 87 } 88} 89