Home | History | Annotate | Download | only in graphics
      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