1 /* 2 * Copyright (C) 2017 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 @file:Suppress("NOTHING_TO_INLINE") 18 19 package androidx.core.graphics 20 21 import android.graphics.Point 22 import android.graphics.Rect 23 import android.graphics.Region 24 import android.graphics.RegionIterator 25 26 /** 27 * Return true if the region contains the specified [Point]. 28 */ 29 inline operator fun Region.contains(p: Point) = contains(p.x, p.y) 30 31 /** 32 * Return the union of this region and the specified [Rect] as a new region. 33 */ 34 inline operator fun Region.plus(r: Rect): Region { 35 return Region(this).apply { 36 union(r) 37 } 38 } 39 40 /** 41 * Return the union of this region and the specified region as a new region. 42 */ 43 inline operator fun Region.plus(r: Region): Region { 44 return Region(this).apply { 45 op(r, Region.Op.UNION) 46 } 47 } 48 49 /** 50 * Return the difference of this region and the specified [Rect] as a new region. 51 */ 52 inline operator fun Region.minus(r: Rect): Region { 53 return Region(this).apply { 54 op(r, Region.Op.DIFFERENCE) 55 } 56 } 57 58 /** 59 * Return the difference of this region and the specified region as a new region. 60 */ 61 inline operator fun Region.minus(r: Region): Region { 62 return Region(this).apply { 63 op(r, Region.Op.DIFFERENCE) 64 } 65 } 66 67 /** 68 * Returns the negation of this region as a new region. 69 */ 70 inline operator fun Region.unaryMinus(): Region { 71 return Region(bounds).apply { 72 op(this@unaryMinus, Region.Op.DIFFERENCE) 73 } 74 } 75 76 /** 77 * Returns the negation of this region as a new region. 78 */ 79 inline operator fun Region.not() = -this 80 81 /** 82 * Return the union of this region and the specified [Rect] as a new region. 83 */ 84 inline infix fun Region.and(r: Rect) = this + r 85 86 /** 87 * Return the union of this region and the specified region as a new region. 88 */ 89 inline infix fun Region.and(r: Region) = this + r 90 91 /** 92 * Return the intersection of this region and the specified [Rect] as a new region. 93 */ 94 inline infix fun Region.or(r: Rect): Region { 95 return Region(this).apply { 96 op(r, Region.Op.INTERSECT) 97 } 98 } 99 100 /** 101 * Return the intersection of this region and the specified region as a new region. 102 */ 103 inline infix fun Region.or(r: Region): Region { 104 return Region(this).apply { 105 op(r, Region.Op.INTERSECT) 106 } 107 } 108 109 /** 110 * Return the union minus the intersection of this region and the specified [Rect] 111 * as a new region. 112 */ 113 inline infix fun Region.xor(r: Rect): Region { 114 return Region(this).apply { 115 op(r, Region.Op.XOR) 116 } 117 } 118 119 /** 120 * Return the union minus the intersection of this region and the specified region 121 * as a new region. 122 */ 123 inline infix fun Region.xor(r: Region): Region { 124 return Region(this).apply { 125 op(r, Region.Op.XOR) 126 } 127 } 128 129 /** Performs the given action on each rect in this region. */ 130 inline fun Region.forEach(action: (rect: Rect) -> Unit) { 131 val iterator = RegionIterator(this) 132 while (true) { 133 val r = Rect() 134 if (!iterator.next(r)) { 135 break 136 } 137 action(r) 138 } 139 } 140 141 /** Returns an [Iterator] over the rects in this region. */ 142 operator fun Region.iterator() = object : Iterator<Rect> { 143 private val iterator = RegionIterator(this@iterator) 144 private val rect = Rect() 145 private var hasMore = iterator.next(rect) 146 147 override fun hasNext() = hasMore 148 149 override fun next(): Rect { 150 if (hasMore) { 151 val r = Rect(rect) 152 hasMore = iterator.next(rect) 153 return r 154 } 155 throw IndexOutOfBoundsException() 156 } 157 } 158