1 /* 2 * Copyright 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 17 package androidx.graphics.shapes 18 19 import android.graphics.Bitmap 20 import android.graphics.Canvas 21 import android.graphics.Color 22 import android.graphics.Paint 23 import android.graphics.Path 24 import androidx.core.graphics.scaleMatrix 25 import androidx.test.filters.SmallTest 26 import org.junit.Test 27 28 @SmallTest 29 class MorphTest { 30 31 val RADIUS = 50 32 val SCALE = RADIUS.toFloat() 33 34 val poly1 = RoundedPolygon(3, centerX = .5f, centerY = .5f) 35 val poly2 = RoundedPolygon(4, centerX = .5f, centerY = .5f) 36 val morph11 = Morph(poly1, poly1) 37 val morph12 = Morph(poly1, poly2) 38 39 /** 40 * Simple test to verify that a Morph with the same start and end shape has curves equivalent to 41 * those in that shape. 42 */ 43 @Test cubicsTestnull44 fun cubicsTest() { 45 val p1Cubics = poly1.cubics 46 val cubics11 = morph11.asCubics(0f) 47 assert(cubics11.size > 0) 48 // The structure of a morph and its component shapes may not match exactly, because morph 49 // calculations may optimize some of the zero-length curves out. But in general, every 50 // curve in the morph *should* exist somewhere in the shape it is based on, so we 51 // do an exhaustive search for such existence. Note that this assertion only works because 52 // we constructed the Morph from/to the same shape. A Morph between different shapes 53 // may not have the curves replicated exactly. 54 for (morphCubic in cubics11) { 55 var matched = false 56 for (p1Cubic in p1Cubics) { 57 if (cubicsEqualish(morphCubic, p1Cubic)) { 58 matched = true 59 continue 60 } 61 } 62 assert(matched) 63 } 64 } 65 66 /** 67 * This test checks to see whether a morph between two different polygons is correct at the 68 * start (progress 0) and end (progress 1). The actual cubics of the morph vs the polygons it 69 * was constructed from may differ, due to the way the morph is constructed, but the rendering 70 * result should be the same. 71 */ 72 @Test morphDrawingTestnull73 fun morphDrawingTest() { 74 // Shapes are in canonical size of 2x2 around center (.5, .5). Translate/scale to 75 // get a larger path 76 val m = scaleMatrix(SCALE, SCALE) 77 m.postTranslate(SCALE / 2f, SCALE / 2F) 78 val poly1Path = poly1.toPath() 79 poly1Path.transform(m) 80 val poly2Path = poly2.toPath() 81 poly2Path.transform(m) 82 val morph120Path = morph12.toPath(0f) 83 morph120Path.transform(m) 84 val morph121Path = morph12.toPath(1f) 85 morph121Path.transform(m) 86 87 val polyBitmap = Bitmap.createBitmap(RADIUS * 2, RADIUS * 2, Bitmap.Config.ARGB_8888) 88 val morphBitmap = Bitmap.createBitmap(RADIUS * 2, RADIUS * 2, Bitmap.Config.ARGB_8888) 89 val polyCanvas = Canvas(polyBitmap) 90 val morphCanvas = Canvas(morphBitmap) 91 92 // Check that the morph at progress 0 is equivalent to poly1 93 drawTestPath(polyCanvas, poly1Path) 94 drawTestPath(morphCanvas, morph120Path) 95 assertBitmapsEqual(polyBitmap, morphBitmap) 96 97 // Check that the morph at progress 1 is equivalent to poly2 98 drawTestPath(polyCanvas, poly2Path) 99 drawTestPath(morphCanvas, morph121Path) 100 assertBitmapsEqual(polyBitmap, morphBitmap) 101 } 102 103 /** Utility function - Fill the canvas with black and draw the path in white. */ drawTestPathnull104 private fun drawTestPath(canvas: Canvas, path: Path) { 105 canvas.drawColor(Color.BLACK) 106 val paint = Paint() 107 paint.isAntiAlias = false 108 paint.style = Paint.Style.FILL 109 paint.color = Color.WHITE 110 canvas.drawPath(path, paint) 111 } 112 } 113