1 /* 2 * Copyright (C) 2008 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 android.graphics.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 22 import android.graphics.Bitmap; 23 import android.graphics.Bitmap.Config; 24 import android.graphics.Canvas; 25 import android.graphics.Color; 26 import android.graphics.Paint; 27 import android.graphics.Paint.Align; 28 import android.graphics.PaintFlagsDrawFilter; 29 import android.graphics.Rect; 30 import android.support.test.filters.SmallTest; 31 import android.support.test.runner.AndroidJUnit4; 32 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 36 @SmallTest 37 @RunWith(AndroidJUnit4.class) 38 public class PaintFlagsDrawFilterTest { 39 private static final float TEXT_SIZE = 20; 40 private static final float TEXT_X = 50; 41 private static final float TEXT_Y = 50; 42 private static final String TEXT = "Test"; 43 private static final int BITMAP_WIDTH = 100; 44 private static final int BITMAP_HEIGHT = 100; 45 46 private float mTextWidth; 47 48 @Test 49 public void testPaintFlagsDrawFilter() { 50 Bitmap bitmapWithoutFilter = drawText(null); 51 52 PaintFlagsDrawFilter filter = new PaintFlagsDrawFilter(Paint.UNDERLINE_TEXT_FLAG, 0); 53 Bitmap bitmapWithFilter = drawText(filter); 54 55 Bitmap combined = delta(bitmapWithoutFilter, bitmapWithFilter); 56 verifyUnderline(combined); 57 } 58 59 private Bitmap drawText(PaintFlagsDrawFilter filter) { 60 Paint p = new Paint(Paint.UNDERLINE_TEXT_FLAG); 61 p.setColor(Color.RED); 62 p.setTextSize(TEXT_SIZE); 63 p.setTextAlign(Align.CENTER); 64 mTextWidth = p.measureText(TEXT); 65 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888); 66 Canvas c = new Canvas(b); 67 c.setDrawFilter(filter); 68 c.drawColor(Color.BLACK); 69 c.drawText(TEXT, TEXT_X, TEXT_Y, p); 70 return b; 71 } 72 73 private Bitmap delta(Bitmap bitmapWithoutFilter, Bitmap bitmapWithFilter) { 74 Bitmap combinedBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888); 75 combinedBitmap.eraseColor(Color.BLACK); 76 int pixelWithoutFilter; 77 int pixelWithFilter; 78 for (int i = 0; i < BITMAP_WIDTH; i++) { 79 for (int j = 0; j < BITMAP_HEIGHT; j++) { 80 pixelWithoutFilter = bitmapWithoutFilter.getPixel(i, j); 81 pixelWithFilter = bitmapWithFilter.getPixel(i, j); 82 if (pixelWithoutFilter != pixelWithFilter) { 83 assertEquals(Color.RED, pixelWithoutFilter); 84 assertEquals(Color.BLACK, pixelWithFilter); 85 combinedBitmap.setPixel(i, j, Color.RED); 86 } 87 } 88 } 89 return combinedBitmap; 90 } 91 92 private void verifyUnderline(Bitmap bitmap) { 93 // Find smallest rectangle containing all RED pixels 94 Rect rect = new Rect(BITMAP_WIDTH, BITMAP_HEIGHT, 0, 0); 95 for (int y = 0; y < BITMAP_HEIGHT; y++) { 96 for (int x = 0; x < BITMAP_WIDTH; x++) { 97 int pixel = bitmap.getPixel(x, y); 98 if (pixel == Color.RED) { 99 rect.left = Math.min(rect.left, x); 100 rect.right = Math.max(rect.right, x); 101 rect.top = Math.min(rect.top, y); 102 rect.bottom = Math.max(rect.bottom, y); 103 } 104 } 105 } 106 // underline is at least one pixel high 107 assertTrue(rect.top <= rect.bottom); 108 // underline is roughly the same length at the text (5% tolerance) 109 assertEquals(mTextWidth, rect.right - rect.left, mTextWidth * 0.053); 110 // underline is under the text or at least at the bottom of it 111 assertTrue(rect.top >= TEXT_Y); 112 } 113 114 // Tests that FILTER_BITMAP_FLAG is handled properly. 115 @Test 116 public void testPaintFlagsDrawFilter2() { 117 // Create a bitmap with alternating black and white pixels. 118 int kWidth = 5; 119 int kHeight = 5; 120 int colors[] = new int [] { Color.WHITE, Color.BLACK }; 121 int k = 0; 122 Bitmap grid = Bitmap.createBitmap(kWidth, kHeight, Config.ARGB_8888); 123 for (int i = 0; i < kWidth; ++i) { 124 for (int j = 0; j < kHeight; ++j) { 125 grid.setPixel(i, j, colors[k]); 126 k = (k + 1) % 2; 127 } 128 } 129 130 // Setup a scaled canvas for drawing the bitmap, with and without FILTER_BITMAP_FLAG set. 131 // When the flag is set, there will be gray pixels. When the flag is not set, all pixels 132 // will be either black or white. 133 int kScale = 5; 134 Bitmap dst = Bitmap.createBitmap(kWidth * kScale, kHeight * kScale, Config.ARGB_8888); 135 Canvas canvas = new Canvas(dst); 136 canvas.scale(kScale, kScale); 137 138 // Drawn without FILTER_BITMAP_FLAG, all pixels will be black or white. 139 Paint simplePaint = new Paint(); 140 canvas.drawBitmap(grid, 0, 0, simplePaint); 141 142 verifyContainsOnlyBlackAndWhite(dst); 143 144 // Drawn with FILTER_BITMAP_FLAG, some pixels will be somewhere in between. 145 Paint filterBitmapPaint = new Paint(Paint.FILTER_BITMAP_FLAG); 146 canvas.drawBitmap(grid, 0, 0, filterBitmapPaint); 147 148 verifyContainsNonBW(dst); 149 150 // Drawing with a paint that FILTER_BITMAP_FLAG set and a DrawFilter that removes 151 // FILTER_BITMAP_FLAG should remove the effect of the flag, resulting in all pixels being 152 // either black or white. 153 canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0)); 154 canvas.drawBitmap(grid, 0, 0, filterBitmapPaint); 155 156 verifyContainsOnlyBlackAndWhite(dst); 157 158 // Likewise, drawing with a DrawFilter that sets FILTER_BITMAP_FLAG should filter, 159 // resulting in gray pixels. 160 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG)); 161 canvas.drawBitmap(grid, 0, 0, simplePaint); 162 163 verifyContainsNonBW(dst); 164 } 165 166 // Assert that at least one pixel is neither black nor white. This is used to verify that 167 // filtering was done, since the original bitmap only contained black and white pixels. 168 private void verifyContainsNonBW(Bitmap bitmap) { 169 for (int i = 0; i < bitmap.getWidth(); ++i) { 170 for (int j = 0; j < bitmap.getHeight(); ++j) { 171 int color = bitmap.getPixel(i, j); 172 if (color != Color.BLACK && color != Color.WHITE) { 173 // Filtering must have been done. 174 return; 175 } 176 } 177 } 178 // Filtering did not happen. 179 assertTrue(false); 180 } 181 182 // Assert that every pixel is either black or white. Used to verify that no filtering was 183 // done, since the original bitmap contained only black and white pixels. 184 private void verifyContainsOnlyBlackAndWhite(Bitmap bitmap) { 185 for (int i = 0; i < bitmap.getWidth(); ++i) { 186 for (int j = 0; j < bitmap.getHeight(); ++j) { 187 int color = bitmap.getPixel(i, j); 188 assertTrue(color == Color.BLACK || color == Color.WHITE); 189 } 190 } 191 } 192 } 193