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