1 /* 2 * Copyright (C) 2009 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 package android.graphics.cts; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertTrue; 20 21 import android.graphics.Bitmap; 22 import android.graphics.Bitmap.Config; 23 import android.graphics.Canvas; 24 import android.graphics.Color; 25 import android.graphics.CornerPathEffect; 26 import android.graphics.Paint; 27 import android.graphics.Paint.Style; 28 import android.graphics.Path; 29 import android.graphics.PathEffect; 30 import android.graphics.PorterDuff.Mode; 31 import android.graphics.PorterDuffXfermode; 32 import android.graphics.RectF; 33 34 import androidx.test.filters.SmallTest; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 40 @SmallTest 41 @RunWith(AndroidJUnit4.class) 42 public class CornerPathEffectTest { 43 private static final int BITMAP_WIDTH = 100; 44 private static final int BITMAP_HEIGHT = 100; 45 private static final int PADDING = 10; 46 private static final int RADIUS = 20; 47 private static final int TOLERANCE = 5; 48 49 @Test 50 public void testCornerPathEffect() { 51 Path path = new Path(); 52 path.moveTo(0, PADDING); 53 path.lineTo(BITMAP_WIDTH - PADDING, PADDING); 54 path.lineTo(BITMAP_WIDTH - PADDING, BITMAP_HEIGHT); 55 56 PathEffect effect = new CornerPathEffect(RADIUS); 57 58 Paint pathPaint = new Paint(); 59 pathPaint.setColor(Color.GREEN); 60 pathPaint.setStyle(Style.STROKE); 61 pathPaint.setStrokeWidth(0); 62 pathPaint.setPathEffect(effect); 63 64 Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888); 65 Canvas canvas = new Canvas(bitmap); 66 67 // draw the path using the corner path effect 68 canvas.drawPath(path, pathPaint); 69 70 // create a path that describes the expected shape after the corner is rounded 71 Path expectedPath = new Path(); 72 RectF oval = new RectF(BITMAP_WIDTH - PADDING - 2 * RADIUS, PADDING, 73 BITMAP_WIDTH - PADDING, PADDING + 2 * RADIUS); 74 expectedPath.moveTo(0, PADDING); 75 expectedPath.arcTo(oval, 270, 90); 76 expectedPath.lineTo(BITMAP_WIDTH - PADDING, BITMAP_HEIGHT); 77 78 // A paint that draws the expected path with a tolerance width into the red channel 79 Paint expectedPaint = new Paint(); 80 expectedPaint.setColor(Color.RED); 81 expectedPaint.setStyle(Style.STROKE); 82 expectedPaint.setStrokeWidth(TOLERANCE); 83 expectedPaint.setXfermode(new PorterDuffXfermode(Mode.SCREEN)); 84 85 canvas.drawPath(expectedPath, expectedPaint); 86 87 int numPixels = 0; 88 for (int y = 0; y < BITMAP_HEIGHT; y++) { 89 for (int x = 0; x < BITMAP_WIDTH; x++) { 90 int pixel = bitmap.getPixel(x, y); 91 if (Color.green(pixel) > 0) { 92 numPixels += 1; 93 // green path must overlap with red guide line 94 assertEquals(Color.YELLOW, pixel); 95 } 96 } 97 } 98 // number of pixels that should be on a straight line 99 int straightLines = BITMAP_WIDTH - PADDING - RADIUS + BITMAP_HEIGHT - PADDING - RADIUS; 100 // number of pixels forming the corner 101 int cornerPixels = numPixels - straightLines; 102 // rounded corner must have less pixels than a sharp corner 103 assertTrue(cornerPixels < 2 * RADIUS); 104 // ... but not as few as a diagonal 105 assertTrue(cornerPixels > Math.sqrt(2 * Math.pow(RADIUS, 2))); 106 } 107 } 108