• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 android.tools.common.datatypes
18 
19 import android.tools.common.withCache
20 import kotlin.js.JsExport
21 import kotlin.js.JsName
22 
23 /**
24  * Wrapper for RectProto
25  *
26  * ```
27  *     - frameworks/native/services/surfaceflinger/layerproto/common.proto and
28  *     - frameworks/base/core/proto/android/graphics/rect.proto
29  * ```
30  *
31  * This class is used by flicker and Winscope
32  */
33 @JsExport
34 open class Rect(
35     @JsName("left") val left: Int = 0,
36     @JsName("top") val top: Int = 0,
37     @JsName("right") val right: Int = 0,
38     @JsName("bottom") val bottom: Int = 0
39 ) : DataType() {
40     @JsName("height") val height: Int = bottom - top
41     @JsName("width") val width: Int = right - left
centerXnull42     @JsName("centerX") fun centerX(): Int = (left + right) / 2
43     @JsName("centerY") fun centerY(): Int = (top + bottom) / 2
44     /** Returns true if the rectangle is empty (left >= right or top >= bottom) */
45     override val isEmpty: Boolean = width <= 0 || height <= 0
46 
47     /** Returns a [RectF] version fo this rectangle. */
48     @JsName("toRectF")
49     fun toRectF(): RectF {
50         return RectF.from(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
51     }
52 
doPrintValuenull53     override fun doPrintValue() = "($left, $top) - ($right, $bottom)"
54 
55     /**
56      * Returns true iff the specified rectangle r is inside or equal to this rectangle. An empty
57      * rectangle never contains another rectangle.
58      *
59      * @param rect The rectangle being tested for containment.
60      * @return true iff the specified rectangle r is inside or equal to this
61      *
62      * ```
63      *              rectangle
64      * ```
65      */
66     operator fun contains(rect: Rect): Boolean {
67         val thisRect = toRectF()
68         val otherRect = rect.toRectF()
69         return thisRect.contains(otherRect)
70     }
71 
72     /**
73      * Returns a [Rect] where the dimensions don't exceed those of [crop]
74      *
75      * @param crop The crop that should be applied to this layer
76      */
77     @JsName("crop")
cropnull78     fun crop(crop: Rect): Rect {
79         val newLeft = maxOf(left, crop.left)
80         val newTop = maxOf(top, crop.top)
81         val newRight = minOf(right, crop.right)
82         val newBottom = minOf(bottom, crop.bottom)
83         return from(newLeft, newTop, newRight, newBottom)
84     }
85 
86     /**
87      * Returns true if: fLeft <= x < fRight && fTop <= y < fBottom. Returns false if SkIRect is
88      * empty.
89      *
90      * Considers input to describe constructed SkIRect: (x, y, x + 1, y + 1) and returns true if
91      * constructed area is completely enclosed by SkIRect area.
92      *
93      * @param x test SkIPoint x-coordinate @param y test SkIPoint y-coordinate @return true if (x,
94      *   y) is inside SkIRect
95      */
96     @JsName("containsPoint")
containsnull97     fun contains(x: Int, y: Int): Boolean {
98         return x in left until right && y in top until bottom
99     }
100 
101     /**
102      * If the specified rectangle intersects this rectangle, return true and set this rectangle to
103      * that intersection, otherwise return false and do not change this rectangle. No check is
104      * performed to see if either rectangle is empty. To just test for intersection, use
105      * intersects()
106      *
107      * @param rect The rectangle being intersected with this rectangle.
108      * @return A rectangle with the intersection coordinates
109      */
110     @JsName("intersection")
intersectionnull111     fun intersection(rect: Rect): Rect {
112         val thisRect = toRectF()
113         val otherRect = rect.toRectF()
114         return thisRect.intersection(otherRect).toRect()
115     }
116 
117     @JsName("clone")
clonenull118     fun clone(): Rect {
119         return from(left, top, right, bottom)
120     }
121 
122     companion object {
123         @JsName("EMPTY")
124         val EMPTY: Rect
<lambda>null125             get() = withCache { Rect() }
126 
127         @JsName("from")
<lambda>null128         fun from(left: Int, top: Int, right: Int, bottom: Int): Rect = withCache {
129             Rect(left, top, right, bottom)
130         }
131 
withoutCachenull132         internal fun withoutCache(left: Int, top: Int, right: Int, bottom: Int): Rect =
133             Rect(left, top, right, bottom)
134     }
135 }
136