1 /*
<lambda>null2 * Copyright 2022 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 androidx.graphics.shapes
18
19 import android.graphics.Bitmap
20 import android.graphics.Matrix
21 import androidx.core.graphics.get
22 import kotlin.math.abs
23 import org.junit.Assert.assertEquals
24 import org.junit.Assert.assertTrue
25
26 private val Epsilon = 1e-4f
27
28 // Test equality within Epsilon
29 internal fun assertPointsEqualish(expected: Point, actual: Point) {
30 val msg = "$expected vs. $actual"
31 assertEquals(msg, expected.x, actual.x, Epsilon)
32 assertEquals(msg, expected.y, actual.y, Epsilon)
33 }
34
equalishnull35 internal fun equalish(f0: Float, f1: Float, epsilon: Float): Boolean {
36 return abs(f0 - f1) < epsilon
37 }
38
pointsEqualishnull39 internal fun pointsEqualish(p0: Point, p1: Point): Boolean {
40 return equalish(p0.x, p1.x, Epsilon) && equalish(p0.y, p1.y, Epsilon)
41 }
42
cubicsEqualishnull43 internal fun cubicsEqualish(c0: Cubic, c1: Cubic): Boolean {
44 return pointsEqualish(Point(c0.anchor0X, c0.anchor0Y), Point(c1.anchor0X, c1.anchor0Y)) &&
45 pointsEqualish(Point(c0.anchor1X, c0.anchor1Y), Point(c1.anchor1X, c1.anchor1Y)) &&
46 pointsEqualish(Point(c0.control0X, c0.control0Y), Point(c1.control0X, c1.control0Y)) &&
47 pointsEqualish(Point(c0.control1X, c0.control1Y), Point(c1.control1X, c1.control1Y))
48 }
49
assertCubicsEqualishnull50 internal fun assertCubicsEqualish(expected: Cubic, actual: Cubic) {
51 assertPointsEqualish(
52 Point(expected.anchor0X, expected.anchor0Y),
53 Point(actual.anchor0X, actual.anchor0Y)
54 )
55 assertPointsEqualish(
56 Point(expected.control0X, expected.control0Y),
57 Point(actual.control0X, actual.control0Y)
58 )
59 assertPointsEqualish(
60 Point(expected.control1X, expected.control1Y),
61 Point(actual.control1X, actual.control1Y)
62 )
63 assertPointsEqualish(
64 Point(expected.anchor1X, expected.anchor1Y),
65 Point(actual.anchor1X, actual.anchor1Y)
66 )
67 }
68
assertCubicListsEqualishnull69 internal fun assertCubicListsEqualish(expected: List<Cubic>, actual: List<Cubic>) {
70 assertEquals(expected.size, actual.size)
71 for (i in expected.indices) {
72 assertCubicsEqualish(expected[i], actual[i])
73 }
74 }
75
assertFeaturesEqualishnull76 internal fun assertFeaturesEqualish(expected: Feature, actual: Feature) {
77 assertCubicListsEqualish(expected.cubics, actual.cubics)
78 assertEquals(expected::class, actual::class)
79
80 if (expected is Feature.Corner && actual is Feature.Corner) {
81 assertEquals(expected.convex, actual.convex)
82 }
83 }
84
assertPolygonsEqualishnull85 internal fun assertPolygonsEqualish(expected: RoundedPolygon, actual: RoundedPolygon) {
86 assertCubicListsEqualish(expected.cubics, actual.cubics)
87
88 assertEquals(expected.features.size, actual.features.size)
89 for (i in expected.features.indices) {
90 assertFeaturesEqualish(expected.features[i], actual.features[i])
91 }
92 }
93
assertPointGreaterishnull94 internal fun assertPointGreaterish(expected: Point, actual: Point) {
95 assertTrue(actual.x >= expected.x - Epsilon)
96 assertTrue(actual.y >= expected.y - Epsilon)
97 }
98
assertPointLessishnull99 internal fun assertPointLessish(expected: Point, actual: Point) {
100 assertTrue(actual.x <= expected.x + Epsilon)
101 assertTrue(actual.y <= expected.y + Epsilon)
102 }
103
assertEqualishnull104 internal fun assertEqualish(expected: Float, actual: Float, message: String? = null) {
105 assertEquals(message ?: "", expected, actual, Epsilon)
106 }
107
assertInBoundsnull108 internal fun assertInBounds(shape: List<Cubic>, minPoint: Point, maxPoint: Point) {
109 for (cubic in shape) {
110 assertPointGreaterish(minPoint, Point(cubic.anchor0X, cubic.anchor0Y))
111 assertPointLessish(maxPoint, Point(cubic.anchor0X, cubic.anchor0Y))
112 assertPointGreaterish(minPoint, Point(cubic.control0X, cubic.control0Y))
113 assertPointLessish(maxPoint, Point(cubic.control0X, cubic.control0Y))
114 assertPointGreaterish(minPoint, Point(cubic.control1X, cubic.control1Y))
115 assertPointLessish(maxPoint, Point(cubic.control1X, cubic.control1Y))
116 assertPointGreaterish(minPoint, Point(cubic.anchor1X, cubic.anchor1Y))
117 assertPointLessish(maxPoint, Point(cubic.anchor1X, cubic.anchor1Y))
118 }
119 }
120
identityTransformnull121 internal fun identityTransform() = PointTransformer { x, y -> TransformResult(x, y) }
122
pointRotatornull123 internal fun pointRotator(angle: Float): PointTransformer {
124 val matrix = Matrix().apply { setRotate(angle) }
125 return PointTransformer { x, y ->
126 val point = floatArrayOf(x, y)
127 matrix.mapPoints(point)
128 TransformResult(point[0], point[1])
129 }
130 }
131
scaleTransformnull132 internal fun scaleTransform(sx: Float, sy: Float) = PointTransformer { x, y ->
133 TransformResult(x * sx, y * sy)
134 }
135
translateTransformnull136 internal fun translateTransform(dx: Float, dy: Float) = PointTransformer { x, y ->
137 TransformResult(x + dx, y + dy)
138 }
139
assertBitmapsEqualnull140 internal fun assertBitmapsEqual(b0: Bitmap, b1: Bitmap) {
141 assertEquals(b0.width, b1.width)
142 assertEquals(b0.height, b1.height)
143 for (row in 0 until b0.height) {
144 for (col in 0 until b0.width) {
145 assertEquals("Pixels at ($col, $row) not equal", b0.get(col, row), b1.get(col, row))
146 }
147 }
148 }
149