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
17package androidx.core.graphics
18
19import android.graphics.Canvas
20import android.graphics.Matrix
21
22/**
23 * Wrap the specified [block] in calls to [Canvas.save]
24 * and [Canvas.restoreToCount].
25 */
26inline fun Canvas.withSave(block: Canvas.() -> Unit) {
27    val checkpoint = save()
28    try {
29        block()
30    } finally {
31        restoreToCount(checkpoint)
32    }
33}
34
35/**
36 * Wrap the specified [block] in calls to [Canvas.save]/[Canvas.translate]
37 * and [Canvas.restoreToCount].
38 */
39inline fun Canvas.withTranslation(
40    x: Float = 0.0f,
41    y: Float = 0.0f,
42    block: Canvas.() -> Unit
43) {
44    val checkpoint = save()
45    translate(x, y)
46    try {
47        block()
48    } finally {
49        restoreToCount(checkpoint)
50    }
51}
52
53/**
54 * Wrap the specified [block] in calls to [Canvas.save]/[Canvas.rotate]
55 * and [Canvas.restoreToCount].
56 */
57inline fun Canvas.withRotation(
58    degrees: Float = 0.0f,
59    pivotX: Float = 0.0f,
60    pivotY: Float = 0.0f,
61    block: Canvas.() -> Unit
62) {
63    val checkpoint = save()
64    rotate(degrees, pivotX, pivotY)
65    try {
66        block()
67    } finally {
68        restoreToCount(checkpoint)
69    }
70}
71
72/**
73 * Wrap the specified [block] in calls to [Canvas.save]/[Canvas.scale]
74 * and [Canvas.restoreToCount].
75 */
76inline fun Canvas.withScale(
77    x: Float = 1.0f,
78    y: Float = 1.0f,
79    pivotX: Float = 0.0f,
80    pivotY: Float = 0.0f,
81    block: Canvas.() -> Unit
82) {
83    val checkpoint = save()
84    scale(x, y, pivotX, pivotY)
85    try {
86        block()
87    } finally {
88        restoreToCount(checkpoint)
89    }
90}
91
92/**
93 * Wrap the specified [block] in calls to [Canvas.save]/[Canvas.skew]
94 * and [Canvas.restoreToCount].
95 */
96inline fun Canvas.withSkew(
97    x: Float = 0.0f,
98    y: Float = 0.0f,
99    block: Canvas.() -> Unit
100) {
101    val checkpoint = save()
102    skew(x, y)
103    try {
104        block()
105    } finally {
106        restoreToCount(checkpoint)
107    }
108}
109
110/**
111 * Wrap the specified [block] in calls to [Canvas.save]/[Canvas.concat]
112 * and [Canvas.restoreToCount].
113 */
114inline fun Canvas.withMatrix(
115    matrix: Matrix = Matrix(),
116    block: Canvas.() -> Unit
117) {
118    val checkpoint = save()
119    concat(matrix)
120    try {
121        block()
122    } finally {
123        restoreToCount(checkpoint)
124    }
125}
126