Home | History | Annotate | Download | only in cts
      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