• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.server.wm.traces.common
18 
19 data class RectF(
20     val left: Float = 0f,
21     val top: Float = 0f,
22     val right: Float = 0f,
23     val bottom: Float = 0f
24 ) {
25     val height: Float get() = bottom - top
26     val width: Float get() = right - left
27 
28     /**
29      * Returns true if the rectangle is empty (left >= right or top >= bottom)
30      */
31     val isEmpty: Boolean
32         get() = width == 0f || height == 0f
33     val isNotEmpty: Boolean
34         get() = !isEmpty
35 
36     /**
37      * Returns a [Rect] version fo this rectangle.
38      *
39      * All fractional parts are rounded to 0
40      */
toRectnull41     fun toRect(): Rect {
42         return Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
43     }
44 
45     /**
46      * Returns true iff the specified rectangle r is inside or equal to this
47      * rectangle. An empty rectangle never contains another rectangle.
48      *
49      * @param r The rectangle being tested for containment.
50      * @return true iff the specified rectangle r is inside or equal to this
51      *              rectangle
52      */
containsnull53     operator fun contains(r: RectF): Boolean {
54         // check for empty first
55         return this.left < this.right && this.top < this.bottom && // now check for containment
56                 left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom
57     }
58 
59     /**
60      * If the rectangle specified by left,top,right,bottom intersects this
61      * rectangle, return true and set this rectangle to that intersection,
62      * otherwise return false and do not change this rectangle. No check is
63      * performed to see if either rectangle is empty. Note: To just test for
64      * intersection, use intersects()
65      *
66      * @param left The left side of the rectangle being intersected with this
67      * rectangle
68      * @param top The top of the rectangle being intersected with this rectangle
69      * @param right The right side of the rectangle being intersected with this
70      * rectangle.
71      * @param bottom The bottom of the rectangle being intersected with this
72      * rectangle.
73      * @return A rectangle with the intersection coordinates
74      */
intersectionnull75     fun intersection(left: Float, top: Float, right: Float, bottom: Float): RectF {
76         if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) {
77             var intersectionLeft = 0f
78             var intersectionTop = 0f
79             var intersectionRight = 0f
80             var intersectionBottom = 0f
81 
82             if (this.left < left) {
83                 intersectionLeft = left
84             }
85             if (this.top < top) {
86                 intersectionTop = top
87             }
88             if (this.right > right) {
89                 intersectionRight = right
90             }
91             if (this.bottom > bottom) {
92                 intersectionBottom = bottom
93             }
94             return RectF(intersectionLeft, intersectionTop, intersectionRight, intersectionBottom)
95         }
96         return EMPTY
97     }
98 
99     /**
100      * If the specified rectangle intersects this rectangle, return true and set
101      * this rectangle to that intersection, otherwise return false and do not
102      * change this rectangle. No check is performed to see if either rectangle
103      * is empty. To just test for intersection, use intersects()
104      *
105      * @param r The rectangle being intersected with this rectangle.
106      * @return A rectangle with the intersection coordinates
107      */
intersectionnull108     fun intersection(r: RectF): RectF = intersection(r.left, r.top, r.right, r.bottom)
109 
110     fun prettyPrint(): String = prettyPrint(this)
111 
112     override fun toString(): String = if (isEmpty) "[empty]" else prettyPrint()
113 
114     companion object {
115         val EMPTY = RectF()
116 
117         fun prettyPrint(rect: RectF): String {
118             val left = FloatFormatter.format(rect.left)
119             val top = FloatFormatter.format(rect.top)
120             val right = FloatFormatter.format(rect.right)
121             val bottom = FloatFormatter.format(rect.bottom)
122             return "($left, $top) - ($right, $bottom)"
123         }
124     }
125 }
126