• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.photoeditor;
18 
19 import android.graphics.Matrix;
20 import android.graphics.RectF;
21 import android.view.View;
22 
23 /**
24  * Utils for rectangles/bounds related calculations.
25  */
26 public 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      */
getStraightenMatrix(RectF bounds, float degrees, Matrix matrix)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      */
postRotateMatrix(float degrees, RectF bounds, Matrix matrix)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      */
postCenterMatrix(RectF contentBounds, View view, Matrix matrix)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      */
getDisplayScale(RectF contentBounds, View view)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