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