1/* 2 * Copyright (C) 2024 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 17import {Point} from 'common/geometry_types'; 18import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 19 20export class Rect { 21 constructor( 22 readonly x: number, 23 readonly y: number, 24 readonly w: number, 25 readonly h: number, 26 ) {} 27 28 static from(node: PropertyTreeNode): Rect { 29 const left = node.getChildByName('left')?.getValue() ?? 0; 30 const top = node.getChildByName('top')?.getValue() ?? 0; 31 const right = node.getChildByName('right')?.getValue() ?? 0; 32 const bottom = node.getChildByName('bottom')?.getValue() ?? 0; 33 return new Rect(left, top, right - left, bottom - top); 34 } 35 36 containsPoint(point: Point): boolean { 37 return ( 38 this.x <= point.x && 39 point.x <= this.x + this.w && 40 this.y <= point.y && 41 point.y <= this.y + this.h 42 ); 43 } 44 45 cropRect(other: Rect): Rect { 46 const maxLeft = Math.max(this.x, other.x); 47 const minRight = Math.min(this.x + this.w, other.x + other.w); 48 const maxTop = Math.max(this.y, other.y); 49 const minBottom = Math.min(this.y + this.h, other.y + other.h); 50 return new Rect(maxLeft, maxTop, minRight - maxLeft, minBottom - maxTop); 51 } 52 53 containsRect(other: Rect): boolean { 54 return ( 55 this.w > 0 && 56 this.h > 0 && 57 this.x <= other.x && 58 this.y <= other.y && 59 this.x + this.w >= other.x + other.w && 60 this.y + this.h >= other.y + other.h 61 ); 62 } 63 64 intersectsRect(other: Rect): boolean { 65 if ( 66 this.x < other.x + other.w && 67 other.x < this.x + this.w && 68 this.y <= other.y + other.h && 69 other.y <= this.y + this.h 70 ) { 71 let [x, y, w, h] = [this.x, this.y, this.w, this.h]; 72 73 if (this.x < other.x) { 74 x = other.x; 75 } 76 if (this.y < other.y) { 77 y = other.y; 78 } 79 if (this.x + this.w > other.x + other.w) { 80 w = other.w; 81 } 82 if (this.y + this.h > other.y + other.h) { 83 h = other.h; 84 } 85 86 return !new Rect(x, y, w, h).isEmpty(); 87 } 88 89 return false; 90 } 91 92 isEmpty(): boolean { 93 const [x, y, w, h] = [this.x, this.y, this.w, this.h]; 94 const nullValuePresent = 95 x === -1 || y === -1 || x + w === -1 || y + h === -1; 96 const nullHeightOrWidth = w <= 0 || h <= 0; 97 return nullValuePresent || nullHeightOrWidth; 98 } 99} 100